我试图将插值表达式与ng-model
指令一起使用,但它不起作用。相反,当我使用ng-src
插值时,它的工作完全正常。这有什么不同?
答案 0 :(得分:3)
这一切都取决于指令的设置方式。
某些指令(如ng-model
,ng-show
和ng-click
不使用插值符号,而指令ng-src
采用插值。
仅对字符串起作用的指令支持插值。如果我们看一下ng-src实现,你会发现
attr.$observe(normalized, function(value) {
if (!value)
return;
attr.$set(attrName, value);
if (msie) element.prop(attrName, attr[attrName]);
});
attr.$observe
监视属性而非模型的变化。模型更改会导致属性更改(由于插值),从而导致触发器触发。
对于像ng-model
这样的所有其他指令,属性值是一个在当前范围内计算的表达式,并不限于字符串值。
如果您正在开发自己的指令,隔离的范围属性=
和@
可帮助您实现类似的功能。
答案 1 :(得分:0)
当指令中的代码查看属性时:插值之前或之后。
我怀疑ngModel
使用了该属性,我的意思是将其传递给$parse
或$eval
,因为它是之前插值。
但是,指令ngSrc
使用该属性,我的意思是将src
属性设置为属性值,插入之后
为什么ngModel
在插值之前使用该值的原因,但是ngSrc
之后使用它,我怀疑它是如何编码的。考虑指令
<my-directive my-attr="{{ 'name' }}"></my-directive>
编码为:
app.directive('myDirective', function() {
return {
restrict: 'E',
link: function($scope, $element, $attrs) {
console.log('Link:', $attrs.myAttr); // Outputs "name"
},
controller: function($scope, $element, $attrs) {
console.log('Controller:', $attrs.myAttr); // Outputs "{{ 'name' }}"
}
};
});
在控制器中可以看到未插值的值,但在链接功能中可以看到后插值。所以(相关)事件的顺序是
你可以see this example in a Plunker。我怀疑ngModel
使用控制器中的值,因此看到预插值,但ngSrc
使用链接函数,因此看到后插值。
为什么ngModel
使用控制器而不是链接函数的一个原因,我怀疑它是否可以将控制器暴露给其他指令,这些指令可以通过require
选项使用它。 / p>
一个稍微有点混淆的并发症是ngSrc
不希望该属性是有效的Angular表达式。它不是通过$parse
或$eval
传递,而是直接使用属性的后插值。 (即它不需要将URL包装在引号中)。
如果您愿意,可以编写一个将插值与Angular表达式结合起来的指令。在链接功能中,您可以将属性传递给$parse
或$eval
。如果后插值的值是有效的Angular表达式,这将起作用。您可以从控制器执行相同的操作,但您必须先通过$interpolate
传递值。
正如您所发现的,ngModel
不支持此功能。但是,我不明白为什么你不能写一些支持这两者的基本版ngModel
,因此可以用作
my-model="myScope{{ 'VariableName' }}"
访问范围变量myScopeVariableName
。
为了再次回到问题,为什么ngModel
本身不支持这一点,我怀疑是因为用例有限(OP在问题中没有提到一个),所以会添加指令的复杂性没有充分的理由。
答案 2 :(得分:-1)
它与指令隔离范围提供的单向与双向数据绑定有关。查看&#34;隔离范围说明&#34;以下部分:
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/