[Angular]当我们将两个控制器引用为“vm”时会发生什么?

时间:2017-06-28 20:25:33

标签: angularjs angularjs-directive angularjs-scope

我正在尝试了解下面代码中究竟发生了什么。

我接受了两个名为widget和filter的指令(我们可以说是sibilings)。

对于这两个我给控制器作为参考“vm”然后它不起作用。

  • 这意味着只有一个controllerAs参考暴露给DOM (这里的widget控件作为参考公开。我不知道为什么?)

如果我更改其中任何一个控制器作为其他内容的参考,那么它工作正常。

  • 两个控制器参考都暴露给DOM获得预期结果。

请你以角度说明这个功能。 当我们给出相同的控制器作为指令的参考时,角度如何评估(这里是兄弟姐妹)。

如果不明确?  由于每个控制器都有自己的范围,那么它将如何模糊不清?

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

});

3 个答案:

答案 0 :(得分:4)

您的指令都没有定义自己的范围,所以它们都使用外部范围(即根范围,这里),并且都尝试将其控制器分配给此范围的属性s = '\n'.join([' '.join([s for s in x.strip(' ').split(' ') if s!='']) for x in ''.join(l).split('\n')]) # OR t = '\n'.join(map(lambda x: ' '.join(filter(lambda s: s!='', x.strip(' ').split(' '))), ''.join(l).split('\n'))) 。所以最后一个赢了。

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

vm

答案 1 :(得分:0)

您应该通过添加返回的对象来隔离至少一个(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');
       }
   };

 });

答案 2 :(得分:0)

如果您希望兄弟指令具有不同的继承范围,请使用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属性。