Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : How to create a two-way data binding between two isolated controllers and a shared service?

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. :)

like image 215
akashivskyy Avatar asked May 20 '14 09:05

akashivskyy


People also ask

How can we share the data between controllers in AngularJS?

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.

Which object is used for two way data binding in AngularJS?

Without $scope object performs two-way binding in AngularJS. Advantages of AngularJS. Difference between One-way and Two-way data binding.

How create data binding in AngularJS explain with example?

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.


3 Answers

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;
});
like image 194
link Avatar answered Oct 04 '22 11:10

link


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"

like image 42
Owen Avatar answered Oct 04 '22 12:10

Owen


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>
like image 28
stefan Avatar answered Oct 04 '22 11:10

stefan