$ watch不会触发已包含的指令

时间:2019-05-07 12:23:52

标签: angularjs

我正在使用angularjs,我为应用程序编写了一个组合框和一个tabs指令,我想这样使用它:

<tabs>
   <tab>Some content</tab>
   <tab>Some other content 
     <my-combobox options="options" selection="selection">
   </tab>
</tab>

我的问题是,目前,当组合框位于选项卡中时,我无法观看组合框更改的属性,这意味着如果我这样做:

$scope.$watch("selection", function(){
     console.log("this code doesn't run when selection changes")
});

当用户从组合框中选择项目时,我的手表不会启动。

让我感到困惑的是,当我从选项卡中取出组合框时,它确实可以工作

<!-- The watch works where -->
<my-combobox options="options" selection="selection"> 
<tabs>
   <tab>Some content</tab>
   <tab>Some other content</tab>
</tab>

所以我的问题是,这些选项卡如何影响包含在其中的元素的观察以及如何解决?

这是tabs指令的代码:

angular.module("ip").directive("tabs", [function () {
    return {
        restrict: "E",
        replace: true,
        transclude: true,
        templateUrl: "/Content/Directives/tabs.html",
        bindToController: true,
        controllerAs: "tabsController",
        scope: {
            onTabSelected: "=?"
        },
        controller: function () {
            var self = this;
            self.tabs = [];

            self.addTab = function (tab) {
                self.tabs.push(tab);

                if (self.tabs.length === 1) {
                    tab.active = true;
                    self.onTabSelected(tab);
                }
            }

            self.select = function (selectedTab) {
                angular.forEach(self.tabs, function (tab) {
                    if (tab.active && tab !== selectedTab) {
                        tab.active = false;
                    }
                });

                selectedTab.active = true;
                if (self.onTabSelected) { self.onTabSelected(selectedTab); }
            }
        }
    };
}]);

(编辑) 这是我的tabs.html文件的代码:

<div class="ip-tabs">
    <ul>
        <li role="presentation" ng-repeat="tab in tabs" ng-click="select(tab)" ng-class="tab.active ? 'active' : ''">
            <span>{{tab.tabTitle}}</span>
        </li>
    </ul>

    <ng-transclude>
    </ng-transclude>
</div>

还有tab.js指令

angular.module("ip").directive("tab", [function () {
    return {
        restrict: "E",
        replace: true,
        transclude: true,
        templateUrl: "/Content/Directives/tab.html",
        require: "^tabs",
        scope: {
            tabTitle: "@"
        },
        link: function (scope, element, attr, tabsCtrl) {
            scope.active = false;
            tabsCtrl.addTab(scope);
        }
    };
}]);

1 个答案:

答案 0 :(得分:1)

这是一个数据隐藏问题。正确且有效的DEMO on PLNKR

  <body ng-app="app" ng-init="x={}">
    <select ng-model="x.selection">
       <option value="a">A</option>
       <option value="b">B</option>
       <option value="c">C</option>
    </select>
    selection={{x.selection}}
    <tabs>
      <tab>Some content</tab>
      <tab>Some other content selection={{x.selection}}<br>
         <my-combobox options="options" selection="x.selection">
         </my-combobox>
      </tab>
   </tabs>
  </body>

作用域继承通常是直截了当的...直到需要 2-way数据绑定。。如果尝试绑定到原始(例如,数字,字符串,布尔值) )在子作用域内的父作用域中。它不能像大多数人期望的那样工作。子作用域具有其自己的属性,该属性隐藏/阴影相同名称的父属性。要进行修复,请在模型的父级中定义对象,然后在子级中引用该对象的属性。

有关更多信息,请参见

当指令定义新的隔离范围时,$ compile服务会创建一个单独的新继承范围,用于链接已包含的内容,即文档中所谓的“正确的包含范围”。

请参见