2012-09-19 55 views
5

指令的属性在范围更新时不会更改,它们仍保留初始值。我在这里错过了什么?angularjs中的动态指令

HTML

<ul class="nav nav-pills nav-stacked" navlist> 
    <navelem href="#!/notworking/{{foo}}"></navelem> 
    <navelem href="#!/working">works great</navelem> 
</ul> 

<p>works: {{foo}}</p> 

的Javascript (基于头版上的角选项卡为例)

angular.module('myApp.directives', []). 
directive('navlist', function() { 
    return { 
     scope: {}, 
     controller: function ($scope) { 
      var panes = $scope.panes = []; 

      this.select = function(pane) { 
       angular.forEach(panes, function(pane) { 
        pane.selected = false; 
       }); 
       pane.selected = true; 
      } 

      this.addPane = function(pane) { 
       if (panes.length == 0) 
        this.select(pane); 
       panes.push(pane); 
      } 

     } 
    } 
}). 
directive('navelem', function() { 
    return { 
     require: '^navlist', 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     scope: { href: '@href' }, 
     link: function(scope, element, attrs, tabsCtrl) { 
      tabsCtrl.addPane(scope); 
      scope.select = tabsCtrl.select; 
     }, 
     template: 
      '<li ng-class="{active: selected}" ng-click="select(this)"><a href="{{href}}" ng-transclude></a></li>' 
    }; 
}); 

回答

8

通过在你的指令定义scope: {},它是创造一个isolated scope。 因此,父区段现在从指令中不可见。

如果你想引用父范围,那么你可以把scope: true作为共享 作用域(在相同的指令中)并省略范围声明,只是正常范围嵌套。 或者,如果您只想引用父代的$scope.foo,则可以像在子代指令中那样定义 显式范围变量。

8

有三种类型的指令范围的继承:

  1. 没有“范围:...”或明确scope: false - 不创建新范围。该指令使用与父代相同的作用域。这很简单和方便,但如果您构建可重用组件,则不建议这样做,因为只有在父范围具有定义了指令需要使用/访问的特定范围属性的情况下,指令才可用。
  2. scope: true - 创建一个新范围,由同一元素上的所有指令共享,并具有父范围的正常原型继承。同样,可能不是可重用组件的最佳选择,因为该指令可能不应该访问父范围属性 - 它可能会意外地更改父项中的某些内容。
  3. scope: { ... } - 创建一个新的“孤立”作用域 - 它不会从父作用域原型继承。但是,对象散列(即{...})允许我们定义从父范围派生的本地指令范围属性 - 因此我们可以控制共享哪些属性以及如何共享。
    1. 在父范围属性和指令范围属性之间使用'='来实现强大的双向绑定 - 对范围属性的更改会影响另一个范围属性。
    2. 使用'@'将父级的属性值绑定到指令作用域属性。这基本上是单向绑定。只有父级范围更改会影响指令范围。
    3. 使用'&'绑定到父范围表达式/函数。

为您的特定问题,你需要在你想拥有2路结合其作用域属性的对象哈希来表示。

更多关于指令范围(包括图片),请参见指令这里:What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

指令范围的我读过这也许是最好的解释。谢谢。 – user2734679

0

像马克Rajcok说 - 范围:{}将创建一个新的隔离范围不继承父属性,但是我们仍然可以通过使用$ parent属性来访问这些属性。

控制器:

app.controller('indexController', function($scope) { 
    $scope.test="Hello world!"; 
}); 

指令

app.directive("test", function() { 
    return{ 
     restrict: "A", 
     scope: {}, 
     controller: function($scope){ 
      console.log("directiv $scope.$parent.test: " + $scope.$parent.test); 
      console.log("directiv $scope.test: " + $scope.test); 
     } 
    }; 
}); 

输出:

directiv $scope.$parent.test: Hello world! 
directiv $scope.test: undefined