这个问题已经被打死了,但是我仍然会分享这个问题,以防其他人为AngularJS范围的可怕困境而苦苦挣扎。这将包括=
,<
,@
,&
和::
。完整的文章可以在这里找到。
=
建立双向绑定。更改父级中的属性将导致子级中的更改,反之亦然。
<
建立单向绑定,父母对孩子。更改父级属性将导致子级更改,但更改子级属性不会影响父级属性。
@
会将标签属性的字符串值分配给子属性。如果该属性包含一个表达式,则该子属性会在表达式计算为其他字符串时更新。例如:
<child-component description="The movie title is {{$ctrl.movie.title}}" />
bindings: {
description: '@',
}
在此,description
子作用域中的属性将是expression的当前值"The movie title is {{$ctrl.movie.title}}"
,其中movie
是父作用域中的对象。
&
有点棘手,实际上似乎没有令人信服的理由去使用它。它允许您在父作用域中评估表达式,用子作用域中的变量替换参数。一个例子(plunk):
<child-component
foo = "myVar + $ctrl.parentVar + myOtherVar"
</child-component>
angular.module('heroApp').component('childComponent', {
template: "<div>{{ $ctrl.parentFoo({myVar:5, myOtherVar:'xyz'}) }}</div>",
bindings: {
parentFoo: '&foo'
}
});
给定parentVar=10
,表达式parentFoo({myVar:5, myOtherVar:'xyz'})
将计算为5 + 10 + 'xyz'
,并且组件将呈现为:
<div>15xyz</div>
您什么时候想使用这种复杂的功能?&
人们经常使用它来将父范围内的回调函数传递给子范围。但是,实际上,通过使用'<'传递函数可以实现相同的效果,该效果更直接,并且避免了笨拙的花括号语法传递参数({myVar:5, myOtherVar:'xyz'}
)。考虑:
回调使用&
:
<child-component parent-foo="$ctrl.foo(bar)"/>
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo({bar:'xyz'})">Call foo in parent</button>',
bindings: {
parentFoo: '&'
}
});
回调使用<
:
<child-component parent-foo="$ctrl.foo"/>
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo('xyz')">Call foo in parent</button>',
bindings: {
parentFoo: '<'
}
});
请注意,对象(和数组)是通过引用传递给子作用域的,而不是复制的。这意味着即使是单向绑定,您也在父范围和子范围中使用相同的对象。
要查看实际使用的不同前缀,请打开此插头。
一次性绑定(初始化)使用
::
[官方文档]
AngularJS的更高版本引入了具有一次性绑定的选项,其中子范围属性仅更新一次。通过消除监视父属性的需求,可以提高性能。语法与上面不同。要声明一次性绑定,请::
在component标签的表达式前面添加:
<child-component
tagline = "::$ctrl.tagline">
</child-component>
这会将值传播tagline
到子作用域,而无需建立单向或双向绑定。注意:如果tagline
最初undefined
位于父作用域中,则angular会一直监视它直到更改为止,然后对子作用域中的相应属性进行一次性更新。
摘要
下表显示了前缀如何工作,具体取决于属性是对象,数组,字符串等。