3

in my app I have a wrapper controller that handles some properties dynamically based on other-controllers within it. everything works like a charm if the other-controllers are present/static on load, but as soon as I'm trying to make them dynamic, they stop working.

It was my understanding that the $rootScope is available from everywhere within the app, is that not true?

my JS looks like this:

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

Full example: http://plnkr.co/edit/tAcv1F9y7t9q9XsQ1EFL?p=preview

I know that this would be probably better with directives, but is there any way to make it work with Controllers?

thanks for the help

1 Answer 1

3
  1. Don't try to access the DOM from controller code. Never. It is very bad practice which breaks AngularJS conventions and eventually provides you with bad architecture. This also means you should not create any DOM elements manually from a controller.

    Better to manipulate with the scope itself, not with its visual representation. You can add new models to scope on your button's click, which will be translated to new elements by ng-repeat directive, each with its own controller (remember controllers are instances, not singletons, so that they have separated life cycles).

  2. You might want to make use of <script type="text/ng-template"> and ng-include here instead of hidden divs.

  3. Try to avoid using $rootScope when possible - it is global state which can be dangerous.

It might look like this then (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>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.