[Angular]当我们将两个控制器作为参考 "vm" 时会发生什么?

[Angular]What is happening when we take two controllerAs reference as "vm"?

我想了解下面代码中到底发生了什么。

我采用了两个指令,名为 widget 和 filter(我们可以说是兄弟姐妹)。

对于两者,我都将 controllerAs 参考为 "vm" 然后它不起作用。

如果我将其中任何一个 controllerAs 更改为对其他内容的引用,那么它工作正常。

能否请您在 angular 中解释一下此功能。 angular 当我们为指令提供相同的 controllerAs 参考时如何评估(这里是兄弟)。

如果有歧义? 由于每个控制器都有自己的范围,那么它怎么会模棱两可?

Here you can see the issue.

这是我的指令结构。

    <div ng-app="myApp">
      {{tt.name}}
      <body-dir>
        <icon-dir>
          <filter-dir>

          </filter-dir>
        </icon-dir>

        <widget-dir>

        </widget-dir>
      </body-dir>
</div>

JS:

var myApp = angular.module('myApp', []);
myApp.controller('filterController', function filterController($scope) {
  var vm = this;
  vm.test = "From filter controller";
  alert("filter");
});
myApp.controller('widgetController', ['$scope', function widgetController($scope) {
  var vm = this;
  vm.widget = "From widget controller";
  alert("widget");
}])
myApp.directive('bodyDir', function() {
  return {
    restrict: 'E',
    link: function($scope) {
      alert('body-dir');
    }
  };
});

myApp.directive('widgetDir', function() {
  return {
    restrict: 'E',
    controller: 'widgetController',
    controllerAs: 'vm',
    template: "<span>{{vm.widget}}</span>",
    link: function($scope) {
      alert('widget-dir');
    }
  };

});
myApp.directive('filterDir', function() {
  return {
    controller: 'filterController',
    controllerAs: 'vm', // If I change something else it's working fine
    restrict: 'E',
    template: "<span>{{vm.test}}</span>",
    link: function($scope) {

      alert('filter-dir');
    }
  };
});
myApp.directive('iconDir', function() {
  return {
    restrict: 'E',
    link: function($scope) {
      alert('icon-dir');
    }
  };

});

None 你的指令定义了自己的范围,所以它们都使用外部范围(即这里的根范围),并且都尝试将它们的控制器分配给 属性 vm 这个范围。所以最后一个获胜。

基本上,您的模板代码会导致以下情况发生:

$rootScope.vm = filterController;
$rootscope.vm = widgetController;

您应该通过添加返回的对象来隔离至少一个(2 个指令中的)范围以使您的代码正常工作

    scope : { } or 
    scope : { 
       /* pass here what you'd like the inner (directive) scope 
          to access from the parent controller */ 
         }


    myApp.directive('widgetDir', function() {
     return {
       restrict: 'E',
       controller: 'widgetController',
       controllerAs: 'vm',
       template: "<span>{{vm.widget}}</span>",
       scope : {

       },

       link: function($scope) {
         alert('widget-dir');
       }
   };

 });

如果您希望兄弟指令具有不同的继承范围,请使用scope: true:

    <icon-dir>
    </icon-dir>

    <widget-dir>
    </widget-dir>
myApp.directive('widgetDir', function() {
  return {
    restrict: 'E',
    //DECLARE inherited scope
    scope: true,
    controller: 'widgetController',
    controllerAs: 'vm',
    template: "<span>{{vm.widget}}</span>",
    link: function($scope) {
      alert('widget-dir');
    }
  };

});
myApp.directive('filterDir', function() {
  return {
    restrict: 'E',
    //DECLARE inherited scope
    scope: true,
    controller: 'filterController',
    controllerAs: 'vm', // If I change something else it's working fine
    template: "<span>{{vm.test}}</span>",
    link: function($scope) {

      alert('filter-dir');
    }
  };
});

继承的子作用域 (scope:true) 将在每个兄弟的不同作用域上具有控制器的 vm 属性。