Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS models, multiple $scopes, and two-way data binding

Tags:

angularjs

I like that AngularJS doesn't require and special syntax for Models, but there's one scenario I can't seem to wrap my head around. Take the following

My dataService wraps whatever flavor of data storage I'm using:

app.factory('dataService', function() {
    var data = 'Foo Bar';

    return {
        getData: function() {
            return data;
        }
    };
});

I have two controllers that both access the same piece of data:

app.controller('display', function($scope, dataService) {
    $scope.data = dataService.getData();
});

app.controller('editor', function($scope, dataService) {
    $scope.data = dataService.getData();
});

If I then have two views, one of which modifies the data, why doesn't the other update automatically?

<div ng-controller="display">
<p>{{data}}</p>
</div>

<div ng-controller="editor">
<input type="text" value="{{data}}"/>
</div>

I understand how this is working in something like Knockout where I'd be forced to make the data a knockout observable object. So any modifications in one part of the application trigger subscriptions and update views in another. But I'm not sure how to go about it in Angular.

Any advice?

like image 971
nicholas Avatar asked Apr 01 '13 02:04

nicholas


People also ask

What is two way data binding in AngularJS?

Two-way Binding Data binding in AngularJS is the synchronization between the model and the view. When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well.

Does AngularJS supports two way binding?

AngularJS creates a two way data-binding between the select element and the $ctrl.

What is meant by data binding in AngularJS?

Data-binding in AngularJS apps is the automatic synchronization of data between the model and view components. The way that AngularJS implements data-binding lets you treat the model as the single-source-of-truth in your application.


2 Answers

There are few changes that I would suggest to make it work.

  1. change the data object from a string to object type
  2. Use ng-model to bind the input field

HTML

<div ng-controller="display">
  <p>{{data.message}}</p>
</div>

<div ng-controller="editor">
  <input type="text" ng-model="data.message"/>
</div>

Script

app.factory('dataService', function() {
    var data = {message: 'Foo Bar'};

    return {
        getData: function() {
            return data;
        }
    };
});

Demo: Fiddle

like image 177
Arun P Johny Avatar answered Sep 25 '22 15:09

Arun P Johny


I haven't been stuck with the same situation, but the thing that jumps out at me is what you are sticking in the scope. There was an angular video where scope was discussed. You should put model objects in the scope and not use the scope as your model object.

In your example two scopes will be created each with the string data. Since data is a string and immutable, it will be replaced in scope of editor when changed. In your example if you had dataService return an object and that object is shared between the controllers, then perhaps your problems would be resolved. Try having dataService return model of {data: data} and bind to model.data instead of data.

This is untested, but should work based on how I know angular works.

like image 21
pgreen2 Avatar answered Sep 26 '22 15:09

pgreen2