问题
new to angularJS, after reading the Reference about Scope
If all controllers share a $rootScope in a ng-app, can we share a ng-model which is assigned to the $rootScope, so that controllers could communicate with each other?
Test with the following snippet, but gName failed to change when model in inputController changed, presume may be gName was made $scope.gName again when input changed. if that is true, is there any way to communicate the controller with each other? ie, the input could be displayed in other controllers?
var app = angular.module("myApp",[]);
app.controller("inputController", ["$rootScope", "$scope", function($rootScope, $scope){
$rootScope.gName = "Hello";
}])
.controller("displayController1", ["$rootScope", "$scope", function($rootScope, $scope){
}])
.controller("displayController2", ["$rootScope", "$scope", function($rootScope, $scope){
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<hr/>
<div ng-controller="inputController">
<input type="text" ng-model="gName"/> <br/>
<span>{{gName}}</span>
</div>
<hr/>
<div ng-controller="displayController1">
<span>{{gName}}</span>
</div>
<hr/>
<div ng-controller="displayController2">
<span>{{gName}}</span>
</div>
</body>
回答1:
In AngularJS, $scope inherit from their parent scope (and in the end it will be rootScope)
In Angular, primitive types are overwritten when a child changes them. so in the input when changing gName it is keeping the $rootScope.gName and creating a new local $scope.gName that is only showing on that controller
to solve the problem you can add an object, and changing the property in it
var app = angular.module("myApp",[]);
app.controller("inputController", ["$rootScope", "$scope", function($rootScope, $scope){
$rootScope.prop = { gName: "Hello" };
}])
.controller("displayController1", ["$rootScope", "$scope", function($rootScope, $scope){
}])
.controller("displayController2", ["$rootScope", "$scope", function($rootScope, $scope){
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<hr/>
<div ng-controller="inputController">
<input type="text" ng-model="prop.gName"/> <br/>
<span>{{prop.gName}}</span>
</div>
<hr/>
<div ng-controller="displayController1">
<span>{{prop.gName}}</span>
</div>
<hr/>
<div ng-controller="displayController2">
<span>{{prop.gName}}</span>
</div>
</body>
Note I am only answering the question, this way is not recommended for making controllers communicate with each others, you should use services for that, you can check this guide
回答2:
You do not want your controllers to communicate with each other, as the only purpose of a controller is to transform data from and for the view and to handle view-local logic (like hiding things with checkboxes, previewing calculated numbers and so on).
Your actual data and business logic should be in services, which also allows for multiple controllers to access it.
回答3:
Share logics/data within your application and application controllers through services. The big advantage is that the digest cycle is not influenced by changes, and that your logics/data can easily be shared accross your application on a structured / seperated manner. Usage of service reduce pollution of your readability.
I try to only use the $rootScope for event broadcasting / listening and for data attachment on the main application frame (ex. data in the application outer frame).
AngularJS services are:
Lazily instantiated – AngularJS only instantiates a service when an application component depends on it.
Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.
A detailed example can be followed through a tutorial on https://thinkster.io/a-better-way-to-learn-angularjs/services
来源:https://stackoverflow.com/questions/42134098/is-it-possible-to-bind-a-global-variable-in-ng-model