angularjs中的动态指令

时间:2012-09-19 20:56:39

标签: 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>'
    };
});

3 个答案:

答案 0 :(得分:8)

通过在指令中定义scope: {},它正在创建isolated scope。 因此,父范围现在在指令中是不可见的。

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

答案 1 :(得分:8)

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

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

    有关指令范围(包括图片)的更多信息,请参阅此处的指令部分:What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

答案 2 :(得分:0)

像Mark Rajcok所说 - scope:{}将创建一个新的隔离范围,不会从父级继承属性,但是我们仍然可以通过使用$ 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