I am trying to create a two-way data binding between two isolated controllers and a shared service (which provides another isolated scope):
app.factory("sharedScope", function($rootScope) {
var scope = $rootScope.$new(true);
scope.data = "init text from factory";
return scope;
});
app.controller("first", function($scope, sharedScope) {
$scope.data1 = sharedScope.data;
});
app.controller("second", function($scope, sharedScope) {
$scope.data2 = sharedScope.data;
});
Fiddle: http://jsfiddle.net/akashivskyy/MLuJA/
When the application launches, data1
and data2
are correctly updated to the init text from factory
, but later, if I change any of them, those changes are not reflected throughout those three scopes.
How can I bind them?
P.S. If there's a better way than returning a scope and still having access to event and observing functionalities (without basically re-writing them), let me know. :)
Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.
Without $scope object performs two-way binding in AngularJS. Advantages of AngularJS. Difference between One-way and Two-way data binding.
Two-way Binding When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well. This happens immediately and automatically, which makes sure that the model and the view is updated at all times.
Fixed it. References will be lost if you are using primitives, as in your fiddle.
Check this:
Updated fiddle
app.factory("sharedScope", function($rootScope) {
var scope = $rootScope.$new(true);
scope.data = {text: "init text from factory"};
return scope;
});
app.controller("first", function($scope, sharedScope) {
$scope.data1 = sharedScope.data;
});
app.controller("second", function($scope, sharedScope) {
$scope.data2 = sharedScope.data;
});
Yet another fun bit: In this case, you don't need to inject $scope or $rootScope. The following code works if you utilize Controller As. Check the Fiddle
var app = angular.module("app", []);
app.factory("sharedScope", function() {
var _this = this;
_this.data = {text: "init text from factory"};
return _this;
});
app.controller("first", function(sharedScope) {
var _this = this;
_this.data1 = sharedScope.data;
});
app.controller("second", function(sharedScope) {
var _this = this;
_this.data2 = sharedScope.data;
});
For even more fun, consider controllers, services, and factories as classes. More Fiddles
var app = angular.module("app", []);
var SharedScope = function(){
var _this = this;
_this.data = {text: "init text from factory"};
return _this;
};
app.factory("sharedScope", SharedScope);
var First = function(sharedScope){
var _this = this;
_this.data1 = sharedScope.data;
};
var Second = function(sharedScope){
var _this = this;
_this.data2 = sharedScope.data;
};
First.$inject = ['sharedScope'];
Second.$inject = ['sharedScope'];
app.controller("first", First);
app.controller("second", Second);
I've been playing at implementing Josh Carroll's Guidelines to Avoid "Scope Soup"
JavaScript passes objects by reference, so all scopes will point to the same object. Why not just do this?
app.factory("sharedData", function() {
return {data: "init text from factory"};
});
app.controller("first", function($scope, sharedData) {
$scope.sharedData = sharedData;
});
app.controller("second", function($scope, sharedData) {
$scope.sharedData = sharedData;
});
and in your view:
<p>{{sharedData.data}}</p>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With