Dominic Scanlan Dominic Scanlan - 2 months ago 26
AngularJS Question

Use scope from multiple controllers on page

So i've split out my UI into subcomponents but then i realise that one of the components requires to be react to a dropdown change which is caught by the parent controller.

I can create a shared service for the variables and i have been able to inject the sub controller so that i can kick off functions BUT.

how do i then use the scope within the sub controller?

var ctrl1= $scope.$new();
$controller('ctrl', { $scope: ctrl1});
ctrl1.GetData();


this works fine. I can see data coming back in the console. BUT my ui doesnt change. What am i missing?

I've edited the post to illustrate what i'm attempting to do more clearly.

The drop down on change is caught by the parent controller but i then require the child controller to run away and get some data and update the UI.

It's an attempt to split out the components. Is this possible? Or have a split the components out too far?



<html>

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<script>
angular.module('app2', [])
.controller('ctrl2', ['$scope', '$http', function($scope, $http){
$scope.getdata = function(){
$http.post(WebServiceURL)
.success(function(data){
$scope.app2Data = "test2 data";
});
}
}]);

angular.module('app1', ['app2'])
.controller('ctrl1', ['$scope','$controller',function($scope, $controller){
$scope.name = 'Controller 1';

//just something to put in the ddp
$scope.data = [
{id:1, name: "test"},
{id:2, name: "test2"}
]

$scope.makeChanged = function(id){
//ddp has changed so i refresh the ui with some other data which is in got by ctrl2.
var cl2 = $scope.$new();
$controller('ctrl2', { $scope: cl2 });
cl2.getdata();
}
}]);


</script>

</head>

<body ng-app="app1">

<div ng-controller="ctrl1">
<p>here is: {{name}}</p>

<select ng-model="d" ng-options="d as dat.name for dat in data track by dat.id" ng-change="makeChanged(d.id)"></select>
<div>
{{app2Data.text}}
</div>
</div>
</body>

</html>




Answer

for anyone interested here's how i got round this.

I created a shared service between the two controllers. and created a callback on the service. i registered the call back on ctrl2 so when the shared variable changed the controller2 will do what i want it to and scope is freshed.

<html>

<head>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
  <script>
    angular.module('app1', ['app2'])
      .controller('ctrl1', ['$scope', '$controller', 'appointmentSharedProperties',
        function($scope, appointmentSharedProperties) {
          $scope.name1 = 'Controller 1';
          console.log('ctrl1');
          //just something to put in the ddp
          $scope.data = [{
            id: 1,
            name: 'test'
          }, {
            id: 2,
            name: 'test2'
          }];

          $scope.makeChanged = function(value) {
            //ddp has changed so i refresh the ui with some other data which is in got by ctrl2.
            appointmentSharedProperties.setDetail(value);
            console.log('in makeChanged: ' + value);
          }
        }
      ]).service('appointmentSharedProperties', function() {
        var test = '';
        var __callback = [];
        return {
          getDetail: function() {
            return test;
          },
          setDetail: function(value) {
            test = value;
            if (__callback.length > 0) {
              angular.forEach(__callback, function(callback) {
                callback();
              });
            }
          },
          setCallback: function(callback) {
            __callback.push(callback);
          }

        };
      });


    angular.module('app2', [])
      .controller('ctrl2', ['$scope', 'appointmentSharedProperties',
        function($scope, appointmentSharedProperties) {
          $scope.name2 = 'Controller 2';
          console.log('ctrl2');
          var getdata = function() {
            console.log('in getdata');
            $scope.app2Data = appointmentSharedProperties.getDetail();
          }
          appointmentSharedProperties.setCallback(getdata);
        }
      ]);
  </script>

</head>

<body ng-app="app1">

  <div ng-controller="ctrl1">
    <p>here is: {{name1}}</p>
    <p>here is: {{name2}}</p>

    <select ng-model="d" ng-options="d as dat.name for dat in data track by dat.id" ng-change="makeChanged(d.name)"></select>
    <div>
      {{app2Data}}
    </div>
  </div>
</body>

</html>

Comments