Angularjs指令,采用各种方法来避免{{}}解析问题

时间:2019-02-12 22:07:33

标签: javascript css angularjs

我们有一个有角度的应用程序,最近我们添加了一种机制,可以选择允许用户上传自定义字体,然后以该自定义字体呈现该应用程序。实现它的人抛出了一个指令,该指令声明一个块并根据页面上用户的自定义内容定义字体替代。

调整质量检查小组的原因是,在返回自定义数据之前,他们会看到404请求/ {{fontPath}} / {{customFont}}的请求,直到所有摘要周期结束为止。

我一直在试图使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}}”

我一直在尝试很多事情,以使它消失。我在div和templateUrl内容中都放了ng-cloak。没用

我尝试定义ng-cloak样式并将其设置为样式节点上的css类(在另一篇低级文章中找到了此样式),但是它没有用。

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

template: ``

起初这没用,但是直到我删除url(“ {{fontPath}} {{customFont}}”)周围的引号后才开始。

不清楚模板的原因,解决方式或解决方式,或者为什么解决方法(模板404)比templateUrl更好。我的意思是,根据我发现的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)为什么模板:``最初没有产生404请求就可以工作?

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

3)为什么在大多数浏览器中,带有\ r \ n的笨拙的旧字符串文字在大多数浏览器中呈现相同的效果,但不会产生功能上的影响? Kinda回到了ECMA6模板文字以不同的方式按角度进行评估的理论。

真知灼见。

谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

针对此类情况的典型解决方案是将其包装在

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

这是动态模板的常见模式。加载组件后,请按ID选择脚本,获取其.html()$compile并追加。

由于某种原因,我无法在[SO]上使用它,但是您可以看到它在这种提琴上起作用:https://jsfiddle.net/websiter/khjr70ep/

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

它会应用字体。

答案 1 :(得分:0)

一种方法是在模板内部声明一个具有id属性的空样式标签,例如:

<style id="app-custom-font-css"></style>

然后,当字体已经上传到其最终位置并且您获得了数据时,请使用它来构建CSS内容:

// Update <style> tag with specific ID
const styleTag = document.getElementById('app-custom-font-css');
styleTag.innerHTML = myCustomCssContentString;

以上操作可以通过指令执行或在您的应用加载后完成。希望对您有所帮助。