我知道 Angular 的字符串插值通常对 Handlebars 样式内的表达式进行操作 {{ double curly braces }}
,通过观察我知道我可以在类似的上下文中使用它
- HTML 标记之外的文本:
<span>{{ 'string literal expression ' }}</span>
- HTML 标记内的属性值:
<a href="{{ '/link/to/somewhere' }}">link</a>
而不是自己生成属性,即
-
<a {{ 'href="/link/to/elsewhere"' }}>link</a>
不进行插值。
我很好奇的是为什么:插值发生和不发生的规则是什么,记录在哪里,以及导致这种情况的设计考虑或约束是什么。
我猜这是因为在 Angular 看到文档之前,浏览器已将文档解析为 HTML,因此结构由 HTML 和 {{ stuff }}
决定。即使在插值发生之前,也必须出现在根据 HTML 格式良好的位置。但我很乐意了解整个故事。
最佳答案
插值发生和不发生的地方有哪些规则?
Angular.js 使用 $compile 服务来编译一段 DOM。 The docs说:
The compilation is a process of walking the DOM tree and matching DOM elements to directives.
在compile.js的源代码中有一个函数collectDirectives
,我将其修剪为仅显示相关代码:
function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
var nodeType = node.nodeType;
// ....
switch(nodeType) {
case 1: /* Element */
// ....
// iterate over the attributes
for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
// ....
addAttrInterpolateDirective(node, directives, value, nName);
// ....
}
// ....
break;
case 3: /* Text Node */
addTextInterpolateDirective(directives, node.nodeValue);
break;
case 8: /* Comment */
// ....
break;
}
directives.sort(byPriority);
return directives;
}
如您所见,当 $compile 迭代一段 DOM 时,它仅在属性和文本节点内搜索插值内容。
这些函数,addTextInterpolateDirective
和addAttrInterpolateDirective
“翻译”将插值表达式转换为$watch插值表达式的指令并更新 DOM 元素。
这在哪里记录?
编译阶段记录如下:http://docs.angularjs.org/guide/compiler
它每天都在进步,但仍然有一些深入的东西不清楚,直到你阅读源代码本身。我想有些事情太复杂了,如果不显示代码就无法解释。
导致这种情况的设计考虑或限制是什么?
我想有两个原因:
Angular 在 DOM 节点而不是字符串上运行
,如果 Angular 需要插入属性或元素,那么它应该在 html 字符串上运行,这可能对性能不利。<- 此类事物没有主要用例。
如果您仍然想插入所有内容,请在指令中执行这种魔法:
安example :
app.directive('myAnchor',function(){
return {
restrict: "E",
transclude: true,
link: function(scope,element,attrs,ctrl,$transclude) {
attrs.$observe('interpolate', function(val){
var e = angular.element("<a " + val + "></a>");
$transclude(scope,function(clone){
e.append(clone);
});
element.replaceWith(e);
});
}
};
});
请务必阅读以下内容:
What is the difference between the $parse, $interpolate and $compile services?
关于html - 在什么情况下插值在 Angular 中是合法的,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21108732/