协慌网

登录 贡献 社区

AngularJS 中指令范围内的 '@' 和 '=' 有什么区别?

我仔细阅读了关于该主题的 AngularJS 文档,然后使用指令进行了调整。这是小提琴

以下是一些相关的片段:

  • 来自 HTML:

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
  • 从窗格指令:

    scope: { biTitle: '=', title: '@', bar: '=' },

我有几件事没有得到:

  • 为什么我必须将"{{title}}"'@'"title"'='
  • 我是否也可以直接访问父作用域,而无需使用属性装饰我的元素?
  • 文档说“通常需要通过表达式将数据从隔离范围传递到父范围” ,但这似乎也适用于双向绑定。为什么表达路线会更好?

我找到了另一个显示表达式解决方案的小提琴: http//jsfiddle.net/maxisam/QrCXh/

答案

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

@将本地 / 指令范围属性绑定到DOM 属性计算值 。如果使用title=title1title="title1" ,则 DOM 属性 “title” 的值只是字符串title1 。如果使用title="{{title}}" ,则 DOM 属性 “title” 的值是{{title}}的内插值,因此该字符串将是当前设置的父作用域属性 “title”。由于属性值始终是字符串,因此在使用@时,您将始终在指令范围内以此属性的字符串值结束。

=将本地 / 指令范围属性绑定到父范围属性 。因此,使用= ,您可以使用父模型 / 范围属性名称作为 DOM 属性的值。您不能将{{}}= 一起使用

使用 @,你可以执行title="{{title}} and then some"插入title="{{title}} and then some" - {{title}},然后将字符串 “和它们一些” 连接起来。最终的连接字符串是本地 / 指令范围属性获取的内容。 (你不能用= ,只做@ 。)

对于@ ,如果需要使用 link(ing)函数中的值,则需要使用attr.$observe('title', function(value) { ... }) 。例如, if(scope.title == "...")将无法像您期望的那样工作。请注意,这意味着您只能异步访问此属性。如果仅使用模板中的值,则不需要使用 $ observe()。例如, template: '<div>{{title}}</div>'

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

我是否也可以直接访问父作用域,而无需使用属性装饰我的元素?

是的,但仅限于您不使用隔离范围。从指令中删除此行

scope: { ... }

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

文档说 “通常需要通过表达式将数据从隔离范围传递到父范围”,但这似乎也适用于双向绑定。为什么表达路线会更好?

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

也可以看看

这里有很多很棒的答案,但我想提供一些关于@=& binding 之间差异的观点,这对我来说是有用的。

所有三种绑定都是通过元素的属性将数据从父作用域传递到指令的独立作用域的方法:

  1. @ binding 用于传递字符串。这些字符串支持插值的{{}}表达式。例如: 。内插表达式根据指令的父作用域进行评估。

  2. =绑定用于双向模型绑定。父范围中的模型链接到指令的隔离范围中的模型。对一个模型的更改会影响另一个模型,反之亦然。

  3. binding 用于将方法传递到指令的作用域中,以便可以在指令中调用它。该方法预先绑定到指令的父作用域,并支持参数。例如,如果方法是父作用域中的 hello(name),那么为了从指令内部执行方法,必须调用 $ scope.hello({name:'world'})

我发现通过较短的描述引用范围绑定更容易记住这些差异:

  • @ 属性字符串绑定
  • = 双向模型绑定
  • & 回调方法绑定

符号还使得范围变量在指令实现中的含义更加清晰:

  • @ string
  • = 模特
  • & 方法

为了有用(对我来说反正):

  1. =
  2. @

=表示双向绑定,因此对父作用域的变量的引用。这意味着,当您更改指令中的变量时,它也将在父作用域中更改。

@表示将变量复制(克隆)到指令中。

据我所知, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>应该有效。 bi-title将接收父范围变量值,该值可在指令中更改。

如果需要在父作用域中更改多个变量,则可以在指令中对父作用域执行函数(或通过服务传递数据)。