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

$scope saved is the scope of the last directive in a nested hierarchy

我想嵌套指令并让它们中的每一个都有自己独立的范围。但是,当我点击任何 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);

这是我的小部件的代码 header:

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

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

这里发生的是 tcp-widget-header 共享范围 - 即它使用默认值 scope: false。这意味着当你在示波器上设置一些东西时,就像你对

所做的那样
scope.printId = ctrl.printId;

最后一个 tcp-widget-header "wins" 并将 scope.printId - 所有人都将使用 - 设置为 "its" tcp-widget 控制器。因此,所有人都会调用控制器函数,其中 $scope.Id === 3.

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

创建一个子作用域
.directive('tcpWidgetHeader', function() {
   return {
     scope: true,
     // ... whatever you have
   }
});

但是,等等!!! 为什么 tcp-widget-header 指令共享相同的范围开始,而不是在其父级的独立范围内?

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