Angularjs 为什么可以';t我们使用带“的插值表达式;ng模型“;但可以与“一起使用”;ng src“是吗?”;?

Angularjs 为什么可以';t我们使用带“的插值表达式;ng模型“;但可以与“一起使用”;ng src“是吗?”;?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我试图将插值表达式与ng model指令一起使用,但它不起作用。相反,当我将插值与ngsrc一起使用时,它工作得非常好。这种差异是由什么引起的?这完全取决于指令的设置方式 一些指令,如ng model、ng show和ng click不使用插值符号,而指令ng src采用插值符号 仅对字符串起作用的指令支持插值。如果我们查看ng src实现,您会发现 attr.$observe(normalized, function(value) { if (!value)

我试图将插值表达式与
ng model
指令一起使用,但它不起作用。相反,当我将插值与
ngsrc
一起使用时,它工作得非常好。这种差异是由什么引起的?

这完全取决于指令的设置方式

一些指令,如
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
,属性值是在当前范围内计算的表达式,不限于字符串值


如果您正在开发自己的指令,那么独立的作用域属性
=
@
可以帮助您实现类似的功能

这与指令中的代码何时查看属性有关:插值之前或之后

我怀疑
ngModel
使用了该属性,我的意思是将其传递给
$parse
$eval
,因为它在插值之前是

但是,指令
ngSrc
使用属性,我的意思是在
src
插值之后将
src
属性设置为属性值

为什么
ngModel
在插值之前使用该值,而
ngSrc
在插值之后使用该值,我怀疑这与它们的编码方式有关。考虑指令

<my-directive my-attr="{{ 'name' }}"></my-directive>
在控制器中可以看到未插值,但在链接函数中可以看到后插值。因此,(相关)事件的顺序是

  • 控制员
  • 然后插值
  • 然后连接函数
你可以。我怀疑
ngModel
使用来自控制器的值,因此可以看到预插值,但是
ngSrc
使用链接函数,因此可以看到后插值

我怀疑
ngModel
使用控制器而不是链接功能的一个原因是,它可以将控制器暴露给其他指令,这些指令可以通过其
require
选项使用它


一个稍微复杂的问题是,
ngSrc
不希望属性是有效的角度表达式。它不是通过
$parse
$eval
传递它,而是直接使用属性的后插值。(也就是说,不需要将URL用引号括起来)

如果愿意,可以编写一个指令,将插值与角度表达式结合起来。通过链接函数,可以将属性传递给
$parse
$eval
。如果后插值值是有效的角度表达式,则此操作将有效。您可以从控制器执行相同的操作,但必须首先通过
$interpolate
传递值

正如您所发现的,
ngModel
不支持此功能。然而,我不明白为什么你不能编写一些基本版本的
ngModel
,既支持两者,又可以用作

my-model="myScope{{ 'VariableName' }}"
访问范围变量myScopeVariableName的


再次回到问题上来,为什么
ngModel
本身不支持这一点,我怀疑是因为用例是有限的(OP在问题中没有提到一个),因此会毫无理由地增加指令的复杂性。

这与指令提供的单向数据绑定和双向数据绑定有关。查看以下帖子中的“解释隔离范围”部分:


在回答问题时,您应该尽可能详细说明,而不仅仅是发布链接。有时,当您认为需要在ng模型中插入时,您可以使用索引语法。ng model=“$scope[propertyName].subop”
my-model="myScope{{ 'VariableName' }}"