使用AngularJS将现有控制器动态添加到另一个控制器中

时间:2013-08-14 20:19:48

标签: angularjs

在我的应用程序中,我有一个wrapper控制器,可根据其中的other-controllers动态处理某些属性。如果other-controllers存在/静态加载,一切都像魅力一样,但一旦我试图让它们变得动态,它们就会停止工作。

据我所知, $ rootScope 可以在app内的任何地方使用,这是不是真的?

我的JS看起来像这样:

  var webApp = angular.module("webApp",[]);

  webApp.controller("ControllerA", function($scope, $rootScope){
    $rootScope.cnt = 0;
    $rootScope.cntPlusPlus = function(){
      $rootScope.cnt++;
    };

    $rootScope.controllerBs = [];
    var template = $(".controller-b").html();
    $scope.addControllerB = function(){
      $rootScope.controllerBs.push(template);
    };
  });

  webApp.controller("ControllerB", function($scope, $rootScope){
    $scope.cntPlusPlus = function(){
      console.log("overwrite plus plus");
    }
  }); 

完整示例:http://plnkr.co/edit/tAcv1F9y7t9q9XsQ1EFL?p=preview

我知道使用directives可能会更好,但有没有办法让它与控制器配合使用?

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

  1. 不要尝试从控制器代码访问DOM。决不。打破AngularJS约定并最终为您提供糟糕的架构是非常糟糕的做法。这也意味着您不应该从控制器手动创建任何DOM元素。

    最好使用范围本身进行操作,而不是使用其可视表示进行操作。您可以在按钮的单击上添加新模型到范围,这将通过ng-repeat指令转换为新元素,每个指令都有自己的控制器(记住控制器是实例,而不是单例,因此它们已经分开生命周期)。

  2. 您可能希望在此处使用<script type="text/ng-template">ng-include,而不是隐藏div

  3. 尽可能避免使用$rootScope - 这是一种危险的全局状态。

  4. 它可能看起来像这样(plunker):

    HTML:

    <div class="controller-a" ng-controller="ControllerA">
      Controller A
      <div>
        <button ng-click="cntPlusPlus()">cnt++</button> CNT: {{cnt}}
      </div>
      <button ng-click="addB()">Add B</button>
      <div ng-repeat="B in Bs">
       <div ng-include="'b-template'"></div>
      </div>
    </div>
    <script type="text/ng-template" id="b-template">
      <div ng-controller="ControllerB">this is controller b: <button ng-click="cntPlusPlus()">cnt++</button></div>
    </script>
    

    JS:

      var webApp = angular.module("webApp",[]);
    
      webApp.controller("ControllerA", function($scope){
        $scope.cnt = 0;
        $scope.cntPlusPlus = function(){
          $scope.cnt++;
        };
    
        $scope.Bs = [];
        $scope.addB = function(){
          $scope.Bs.push({});
        };
      });
    
      webApp.controller("ControllerB", function($scope){
        $scope.cntPlusPlus = function(){
          console.log("overwrite plus plus");
          $scope.$parent.$parent.$parent.cnt++;  //should be moved to service
        }
      });      
    </script>