Dominic Scanlan
Dominic Scanlan

Reputation: 1009

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>

Upvotes: 1

Views: 343

Answers (2)

Rama
Rama

Reputation: 1

General example of how to pass variables from one controller to other

<html>
  <head>
    <meta charset="ISO-8859-1">
    <title>Basic Controller</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
    </script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="ctrl1">

    {{greeting}}
    </div>
    <div ng-controller="ctrl2">

    {{dataToHtml2}}
    </div>
  </body>
</html>

This is the javascript file for this

var myApp = angular.module('myApp',[]);

myApp.service('sampleService', function(){
var temp = '';
this.setValue = function(data){
temp = data;
}
this.getValue = function(){
return temp;
}
});

myApp.controller('ctrl1', function($scope,sampleService) {
  $scope.greeting = 'This line is in first controller but I exist in both';
  var data= $scope.greeting;
sampleService.setValue(data);
 });

myApp.controller('ctrl2', function($scope, sampleService){
$scope.dataToHtml2 =sampleService.getValue();
});

Here is the blog that explains this flow : Frequently asked questions in angularjs

It has the demo of what I written. Happy coding..!!

Upvotes: 0

Dominic Scanlan
Dominic Scanlan

Reputation: 1009

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>

Upvotes: 1

Related Questions