我已经仔细阅读了AngularJS关于这个主题的文档,然后摆弄了一个指令。这是小提琴。

以下是一些相关片段:

来自HTML: <窗格bi-title = "标题" title =“{{标题}}>{{文本}}> < /窗格 从窗格指令: scope: {biTitle: '=', title: '@', bar: '='},

有几件事我不明白:

为什么我必须使用“{{title}}”与“@”和“title”与“=”? 我也可以直接访问父范围,而不装饰我的元素与属性? 文档说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?

我发现另一个小提琴,显示表达式解决方案太:http://jsfiddle.net/maxisam/QrCXh/


当前回答

为什么我必须使用“{{title}}”与“@”和“title”与“=”?

@ binds a local/directive scope property to the evaluated value of the DOM attribute. If you use title=title1 or title="title1", the value of DOM attribute "title" is simply the string title1. If you use title="{{title}}", the value of the DOM attribute "title" is the interpolated value of {{title}}, hence the string will be whatever parent scope property "title" is currently set to. Since attribute values are always strings, you will always end up with a string value for this property in the directive's scope when using @.

=将局部/指令作用域属性绑定到父作用域属性。因此,使用=,您使用父模型/作用域属性名作为DOM属性的值。{{}}不能与=一起使用。

使用@,你可以这样做title="{{title}},然后some"——{{title}}被插入,然后字符串"and them some"与它连接。最后一个串接的字符串是local/directive scope属性得到的。(你不能用=,只能用@。)

对于@,您将需要使用attr。$observe('title',函数(值){…})如果你需要在你的link(ing)函数中使用该值。例如,如果范围。Title == "…")不会像你期望的那样工作。注意,这意味着您只能异步访问该属性。 如果只使用模板中的值,则不需要使用$observe()。例如,模板:'<div>{{title}}</div>'。

使用=,您不需要使用$observe。

我也可以直接访问父范围,而不装饰我的元素与属性?

是的,但前提是你不使用孤立的作用域。从指令中删除这一行

范围:{…}

然后你的指令不会创建一个新的作用域。它将使用父作用域。然后,您可以直接访问所有父范围属性。

文档中说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?

是的,双向绑定允许本地/指令作用域和父作用域共享数据。“表达式绑定”允许指令调用由DOM属性定义的表达式(或函数)——您还可以将数据作为参数传递给表达式或函数。因此,如果您不需要与父对象共享数据——您只想调用父对象作用域中定义的函数——您可以使用&语法。

另请参阅

Lukas的孤立范围博客文章(涵盖@,=,&) Dnc253对@和=的解释 我关于作用域的博客般的回答——指令部分(在底部,就在摘要部分之前)有一个孤立作用域和它的父作用域的图片——指令作用域使用@表示一个属性,使用=表示另一个属性 在angularJS中& vs @和=的区别是什么

其他回答

@ and =见其他答案。

一个人抓住了你& TL,博士; &从父函数中获取表达式(不仅仅是其他答案中的例子中的函数),并将其设置为指令中的函数,该函数调用表达式。这个函数能够替换表达式的任何变量(甚至函数名),通过将变量传递给一个对象。

explained & is an expression reference, that means if you pass something like <myDirective expr="x==y"></myDirective> in the directive this expr will be a function, that calls the expression, like: function expr(){return x == y}. so in directive's html <button ng-click="expr()"></button> will call the expression. In js of the directive just $scope.expr() will call the expression too. The expression will be called with $scope.x and $scope.y of the parent. You have the ability to override the parameters! If you set them by call, e.g. <button ng-click="expr({x:5})"></button> then the expression will be called with your parameter x and parent's parameter y. You can override both. Now you know, why <button ng-click="functionFromParent({x:5})"></button> works. Because it just calls the expression of parent (e.g. <myDirective functionFromParent="function1(x)"></myDirective>) and replaces possible values with your specified parameters, in this case x. it could be: <myDirective functionFromParent="function1(x) + 5"></myDirective> or <myDirective functionFromParent="function1(x) + z"></myDirective> with child call: <button ng-click="functionFromParent({x:5, z: 4})"></button>. or even with function replacement: <button ng-click="functionFromParent({function1: myfn, x:5, z: 4})"></button>.

它只是一个表达式,不管它是一个函数,还是多个函数,或者只是比较。你可以替换这个表达式中的任意变量。

例子: 指令模板vs调用代码: Parent已经定义了$scope。x, scope.y美元: parent template: <myDirective expr="x==y"></myDirective> <按钮ng-click = " expr ()></button>调用$scope.x==$scope.y <button ng-click="expr({x: 5})"></按钮>调用5 == $scope.y <button ng-click="expr({x:5, y:6})"></button>调用5 == 6

Parent已经定义了$scope。function1,美元范围。x, scope.y美元: : <myDirective expr="function1(x) + y"></myDirective>

<按钮ng-click = " expr ()></button>调用$scope.function1($scope.x) + $scope.y <button ng-click="expr({x: 5})"></button>调用$scope.function1(5) + $scope.y <button ng-click="expr({x:5, y:6})">调用$scope.function1(5) + 6 指令有$作用域。myFn作为函数: <button ng-click="expr({function1: myFn, x:5, y:6})"></button>调用$scope.myFn(5) + 6

即使作用域是本地的,就像在您的例子中,您也可以通过属性$parent访问父作用域。假设在下面的代码中,标题是在父作用域上定义的。然后你可以通过$parent.title访问title:

link : function(scope) { console.log(scope.$parent.title) },
template : "the parent has the title {{$parent.title}}"

但是,在大多数情况下,使用属性可以更好地获得相同的效果。

我发现“&”符号的一个例子是在ng-repeat中渲染特殊数据结构的指令中,它用于“通过表达式将数据从隔离作用域传递到父作用域”,很有用(并且不能使用双向数据绑定)。

<render data = "record" deleteFunction = "dataList.splice($index,1)" ng-repeat = "record in dataList" > </render>

渲染的一部分是删除按钮,这里通过&从外部作用域附加一个删除函数很有用。在渲染指令中,它是这样的

scope : { data = "=", deleteFunction = "&"},
template : "... <button ng-click = "deleteFunction()"></button>"

2-way数据绑定,即data =" ="不能被使用,因为delete函数会在每个$digest周期上运行,这是不好的,因为记录会立即被删除,并且永远不会呈现。

我们可以简单地使用:-

@:-用于单向数据绑定的字符串值。在一种方式中,数据绑定只能将作用域值传递给指令 =:- for对象值用于双向数据绑定。数据绑定有两种方式,你可以在指令和HTML中改变作用域值。 &:-用于方法和函数。

EDIT

在Angular 1.5及以上版本的组件定义中 有四种不同类型的绑定:

=双向数据绑定:-如果我们改变了值,它会自动更新 <单向绑定:-当我们只想从父作用域读取参数而不更新它时。 @这是字符串参数 &这是为了回调,以防你的组件需要输出一些东西到它的父作用域

我一次性实现了所有可能的选项。

它处理所有的选项:

scope:{
    name:'&'
},

scope:{
    name:'='
},

scope:{
    name:'@'
},

scope:{

},

scope:true,

https://jsfiddle.net/rishulmatta/v7xf2ujm

为什么我必须使用“{{title}}”与“@”和“title”与“=”?

@ binds a local/directive scope property to the evaluated value of the DOM attribute. If you use title=title1 or title="title1", the value of DOM attribute "title" is simply the string title1. If you use title="{{title}}", the value of the DOM attribute "title" is the interpolated value of {{title}}, hence the string will be whatever parent scope property "title" is currently set to. Since attribute values are always strings, you will always end up with a string value for this property in the directive's scope when using @.

=将局部/指令作用域属性绑定到父作用域属性。因此,使用=,您使用父模型/作用域属性名作为DOM属性的值。{{}}不能与=一起使用。

使用@,你可以这样做title="{{title}},然后some"——{{title}}被插入,然后字符串"and them some"与它连接。最后一个串接的字符串是local/directive scope属性得到的。(你不能用=,只能用@。)

对于@,您将需要使用attr。$observe('title',函数(值){…})如果你需要在你的link(ing)函数中使用该值。例如,如果范围。Title == "…")不会像你期望的那样工作。注意,这意味着您只能异步访问该属性。 如果只使用模板中的值,则不需要使用$observe()。例如,模板:'<div>{{title}}</div>'。

使用=,您不需要使用$observe。

我也可以直接访问父范围,而不装饰我的元素与属性?

是的,但前提是你不使用孤立的作用域。从指令中删除这一行

范围:{…}

然后你的指令不会创建一个新的作用域。它将使用父作用域。然后,您可以直接访问所有父范围属性。

文档中说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?

是的,双向绑定允许本地/指令作用域和父作用域共享数据。“表达式绑定”允许指令调用由DOM属性定义的表达式(或函数)——您还可以将数据作为参数传递给表达式或函数。因此,如果您不需要与父对象共享数据——您只想调用父对象作用域中定义的函数——您可以使用&语法。

另请参阅

Lukas的孤立范围博客文章(涵盖@,=,&) Dnc253对@和=的解释 我关于作用域的博客般的回答——指令部分(在底部,就在摘要部分之前)有一个孤立作用域和它的父作用域的图片——指令作用域使用@表示一个属性,使用=表示另一个属性 在angularJS中& vs @和=的区别是什么