$ scope saved是嵌套层次结构中最后一个指令的范围

时间:2015-03-18 03:04:31

标签: angularjs angularjs-directive angularjs-scope

我想嵌套指令并让每个指令都有自己独立的范围。但是,当我点击任何ID按钮时,我每次都会得到ID = 3.

我的代码的实时副本在这里。 http://plnkr.co/edit/Lg29CkN7MkEBsI7uNXR3?p=info

这是我的html文件的一部分:

    <tcp-widget id="1">
        <tcp-widget-header>
            <input type="button" value="ID = 1" ng-click="printId()"/>
        </tcp-widget-header>
        <tcp-widget-body>
            <div style="text-align:left; margin:0 auto; border: 1px solid black; width: 300px; padding: 5px;">
                <div style="color:red">RED by Taylor Swift</div>
            </div>
        </tcp-widget-body>
    </tcp-widget>

    <tcp-widget id="2">
        <tcp-widget-header>
            <input type="button" value="ID = 2" ng-click="printId()"/>
        </tcp-widget-header>
        <tcp-widget-body>
            <div style="text-align:left; margin:0 auto; border: 1px solid black; width: 300px; padding: 5px;">
                <div style="color:blue">BLUE by Big Bang</div>
            </div>
        </tcp-widget-body>
    </tcp-widget>

    <tcp-widget id="3">
        <tcp-widget-header>
            <input type="button" value="ID = 3" ng-click="printId()"/>
        </tcp-widget-header>
        <tcp-widget-body>
            <div style="text-align:left; margin:0 auto; border: 1px solid black; width: 300px; padding: 5px;">
                <div style="color:yellow">YELLOW by Coldplay</div>
            </div>
        </tcp-widget-body>
    </tcp-widget>

这是我的小部件的代码:

(function(app) {
  app.directive('tcpWidget', function() {
    return {
      restrict: 'E',
      scope: {
        id: "="
      },
      controller: function($scope, $element, $attrs) {
        this.printId = function() {
          alert("print id : " + $scope.id);
        };
      }
    };
  });
})(app);

这是我的小部件标题的代码:

(function(app) {
    app.directive('tcpWidgetHeader', function() {
        return {
        restrict: 'E'
                , require: "^tcpWidget"
        , link: function(scope, iElem, iAttrs, ctrl){
                    scope.printId = ctrl.printId;
                }
    };
    });
})(app);

2 个答案:

答案 0 :(得分:2)

这里发生的是tcp-widget-header共享范围 - 即它使用默认的scope: false。这意味着当您在范围上设置某些内容时,就像使用

一样
scope.printId = ctrl.printId;

最后tcp-widget-header“获胜”并将scope.printId - 所有将使用 - 设置为“其”tcp-widget控制器。因此,所有人都将调用该控制器函数$scope.Id === 3

因此,快速解决方法是将scope: true添加到指令定义中。这将为每个tcpWidgetHeader

创建子范围
.directive('tcpWidgetHeader', function() {
   return {
     scope: true,
     // ... whatever you have
   }
});

但是,等等!!! 为什么tcp-widget-header指令与开始时的范围相同,而不是在父母的隔离范围内?

原因是指令的子DOM元素的范围不在该指令范围的范围层次结构中 - 与该指令的template中的指令和表达式不同。因此,从范围的角度来看,它们都“存在”在外部范围内,由所有tcp-widgettcp-widget-headertcp-widget-body指令共享。

答案 1 :(得分:0)

您的tcp-widget-header没有隔离范围,因此您在链接函数中设置scope.printId时始终修改相同(外部)范围。