首页 > 解决方案 > Angularjs 指令,做模板的不同方式来避免 {{}} 解析问题

问题描述

我们有一个 Angular 应用程序,最近我们添加了一种机制,可以选择允许用户上传自定义字体,然后以该自定义字体呈现应用程序。实现它的人投入了一个指令,该指令声明一个块并根据用户在页面上的自定义定义字体覆盖。

对 QA 团队进行调整的是,在自定义数据返回之前,他们会看到 /{{fontPath}}/{{customFont}} 的 404 请求,直到所有摘要周期都完成。

我一直试图让 404 消失,但遇到了一些让我困惑的事情。

首先,这是事情的样子

<div font-override ng-if="customFont"></div>

并且指令 templateUrl 看起来像

<style>
    @font-face {
        font-family: 'FontOverride';
        src: url("{{fontPath}}{{customFont}}") format('woff');
        font-weight: normal;
        font-style: normal;
    }

    @font-face {
        font-family: 'FontOverride';
        src: url("{{fontPath}}{{customFont_bold}}") format('woff');
        font-weight: bold;
        font-style: normal;
    }

    @font-face {
        font-family: 'FontOverride';
        src: url("{{fontPath}}{{customFont_italic}}") format('woff');
        font-weight: normal;
        font-style: italic;
    }

    @font-face {
        font-family: 'FontOverride';
        src: url("{{fontPath}}{{customFont_boldItalic}}") format('woff');
        font-weight: bold;
        font-style: italic;
    }

    .ourApp *:not(.fa) {
        font-family: 'FontOverride' !important;
    }
</style>

并且当 templateUrl 内容被交换时,会立即发出 404 请求“/{{fontPath}}{{customFont}}”

我一直在玩一堆东西,试图让它消失。我将 ng-cloak 放在 div 和 templateUrl 内容中。它没有用。

我尝试定义 ng-cloak 样式并将其设置为样式节点上的 css 类(在另一篇文章堆栈中找到)但它不起作用。

在野兔上,我尝试获取 templateUrl 文件的内容并将其嵌入到带有模板文字的指令代码中

template: ``

起初这不起作用,但在我删除 url("{{fontPath}}{{customFont}}") 周围的引号后开始。

不清楚模板为什么或如何或在什么时候得到解决,或者为什么它比 templateUrl 更好(wrt 404)。我的意思是,根据我对 ECMA6 的发现,实际的模板位是 ${},而不是 {{}}。

然后我在 IE11 中尝试了它(因为我们名义上仍然支持它),当然模板文字在那里不起作用。所以我尝试将多行的东西构建为旧字符串

"<style>\r\n" +
"    @font-face { font-family: 'FontOverride'; src: url('{{fontPath}}{{customFont}}') format('woff'); font-weight: normal; font-style: normal; } \r\n\r\n" +
...
"    .ourApp *: not(.fa) {\r\n         font-family: 'FontOverride' !important;\r\n }\r\n</style>\r\n"

样式的最后一行似乎对换行符/空格更敏感,所以我试图保留它。

这在我尝试过的任何浏览器中都有效。当我检查元素时,Chrome、IE、Edge 都以相同的方式呈现它,但在任何阶段都没有获取或应用字体。Firefox 似乎首先从文字中剥离了换行符。

所以... 1) 为什么 template: `` 一开始就没有产生 404 请求就可以工作?

2)我试图使用 ECMA6 模板文字来获取多行常量;我没想到模板结构可以直接工作,因为 ECMA6 使用 ${} 而不是 {{}},但也许 EMCA6 模板文字也有角度语法?或者也许 angular 正在插入 jquery 语法并成为同义词?

3)为什么带有 \r\n 的笨重旧字符串文字在大多数浏览器中呈现相同但不会产生功能影响?Kinda 回到了 ECMA6 模板文字以不同方式通过 Angular 评估的理论。

见解赞赏。

谢谢。

标签: javascriptcssangularjs

解决方案


在 Angular 在页面中实例化之前,浏览器<style>将解析任何标签(并加载 's)。src这意味着在ng-if应用之前。

您需要存储该标记,而不允许浏览器将其解析为<style>标记。

这种情况的典型解决方案是将其包装在

<script type="text/template">
  <style>...</style>
</script>

这是动态模板的常见模式。加载组件后,按 id 选择脚本,抓取它的.html()$compile然后追加。

出于某种原因,我无法让它在 [SO] 上工作,但你可以看到它在这个小提琴中工作:https ://jsfiddle.net/websiter/khjr70ep/

我没有你的文件,所以我使用了一些随机的谷歌字体,但你可以看到它在解析之前没有加载。

它应用了字体。


推荐阅读