【问题标题】:Angularjs directive: Isolated scope and attrsAngularjs 指令:隔离范围和属性
【发布时间】:2012-12-27 09:10:36
【问题描述】:

请看例子here

foodMeApp.directive('fmRating', function() {
  return {
    restrict: 'E',
    scope: {
      symbol: '@',
      max: '@',
      readonly: '@'
    },
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {

      attrs.max = scope.max = parseInt(scope.max || 5, 10);
...

Angular 需要在隔离作用域对象中定义 symbolmaxreadonly 以从父作用域访问它。

使用here

<fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"></fm-rating>

那么,attrs 的目的是什么?无法访问通过attrs 传递的所有属性。为什么不能将 max 的一个值访问为 attrs.max 而不是 scope.max

为什么要像 attrs.max = scope.max 这样分配回来?

由于这个应用程序是由 Angular 作者编写的,我期待一个原因。

谢谢。

【问题讨论】:

标签: javascript angularjs


【解决方案1】:

attrs 的目的是什么?

在与指令相同的元素上定义的属性有几个目的:

  1. 它们是将信息传递到使用隔离范围的指令的唯一方法。由于指令隔离作用域在原型上不是从父作用域继承的,因此我们需要一种方法来指定要传递给隔离作用域的内容。因此,“对象哈希”中的“@”、“=”和“&”都需要一个属性来指定要传递的数据/信息。
  2. 它们用作指令间通信机制。 (例如,Managing communication between independent AngularJS directives independently
  3. 他们normalize 属性名称。

不能访问所有通过 attrs 传递的属性吗?

可以,但是

  1. 您将没有任何数据绑定。
    '@' 设置单向“字符串”数据绑定(父作用域 → 指令隔离作用域)使用@,您在指令中看到/获得的值始终是字符串,所以如果您尝试,请不要使用它将对象传递给您的指令。
    '=' 设置双向数据绑定(父范围 ↔ 指令隔离范围)。
    如果没有数据绑定,您的指令无法 $watch 或 $observe 自动更改模型/数据。
  2. {{}}s 的属性值会导致问题,因为它们不会被插值。
    假设我们有<my-directive name="My name is {{name}}">,父作用域有$scope.name='Mark'。然后,在链接函数内部,console.log(attrs.name) 生成undefined
    如果 name 是使用“@”定义的隔离范围属性,则 attrs.$observe('name', function(val) { console.log(val) }) 会产生 My name is Mark。 (请注意,在链接函数内部,必须使用 $observe() 来获取插值。)

为什么不能将 max 的值访问为 attrs.max 而不是 scope.max

上面回答了

为什么要像 attrs.max = scope.max 一样赋值?

我能想到这样做的唯一原因是,以防某些其他指令需要查看此属性/值(即指令间通信)。但是,另一个指令需要在此指令之后运行才能使其工作(可以通过 priority 指令设置进行一些控制)。

总结:在具有隔离范围的指令中,通常您不想使用attrs。 (我想这可能是一种将初始化数据/值发送到指令中的方法——即,如果您不需要这些值的数据绑定并且不需要插值。)

【讨论】:

【解决方案2】:

使用 attrs,您可以访问 html 标签中定义的属性,例如

<fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true">

所以在这种情况下,您将可以访问 symbolreadonly 属性。您在自定义指令中定义的每个属性都可用于 attrs 变量。

方块:

attrs.max = scope.max = parseInt(scope.max || 5, 10);

解析并分配当前的 scope.max 值或 5(如果不存在)到 scope.max 和 attrs.max .这样,您可以在分配后从 attrs.max 中读取。在此之前 attrs.max 属性未定义。

检查 fmRating.js 源,我不知道为什么/在哪里/何时使用这段代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多