Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Two way data binding fails if element has ngModel and a directive with a local scope

Tags:

angularjs

The problem is shown here: http://jsfiddle.net/ews7S/

<input type="text" ng-model="testModel" dir="123">

When an element is bound to a model in a controller scope and you also add a directive to the element that has it's own local scope, then changes to the model only change in the directives scope.

like image 976
Atomix Avatar asked Nov 29 '12 18:11

Atomix


People also ask

Is ngModel necessary for two way binding?

Because no built-in HTML element follows the x value and xChange event pattern, two-way binding with form elements requires NgModel .

Which directive is used for two way data binding in Angular?

Two-way data binding can be achieved using a ngModel directive in Angular. The below syntax shows the data binding using (ngModel), which is basically the combination of both the square brackets of property binding and parentheses of the event binding.

What does [( ngModel )] do?

ngModel is responsible for: Binding the view into the model, which other directives such as input , textarea or select require.

Does AngularJS support two way binding?

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


1 Answers

An alternative solution is to use an object for the model, rather than a primitive. Then the new directive scope will inherit (prototypically) a reference to the object, rather than a copy of the primitive's value:

$scope.model = { testProp: "444" };

<input type="text" ng-model="model.testProp" dir="123">
<input type="text" ng-model="model.testProp">

document.getElementById("out").innerHTML = scope.model.testProp;

http://jsfiddle.net/mrajcok/awfU5/

With a primitive, such as $scope.testModel, the directive scope's testModel property gets a copy of the parent scope's testModel's value. Changes to one do not affect the other.

With an object, such as $scope.model, both the parent scope and the directive scope have a reference to the same (one) object. Changes in either affect the same object.

Another (fragile) solution is to use the undocumented $parent property (make these changes to the question fiddle):

<input type="text" ng-model="$parent.testModel" dir="123">

document.getElementById("out").innerHTML = scope.$parent.testModel;

Note that using $parent is a fragile solution because use of $parent depends on the DOM structure. E.g., If another controller was added (explicitly by you, or implicitly by another Angular directive) between the parent and the child (now grandchild), we would then need to use $parent.$parent.testModel.

like image 136
Mark Rajcok Avatar answered Nov 15 '22 22:11

Mark Rajcok