Directive with isolated scope and ng-model
Solution 1
As discussed in the comments, it is generally not recommended to use a child scope (scope: true
or scope: { ... }
) with ng-model. However, since Arun needs to create additional scope properties, scope: true
can be used with an object, not a primitive. This leverages prototypical inheritance, so $parent
is not neeed:
<test-ng-model ng-model="someObj.model" ...>
Solution 2
Because you created an isolated scope, ngModel="model" refers to your new isolated scope. If you want to refer to your AppController scope, you should use $parent:
<test-ng-model ng-model="$parent.model" name="myel"></test-ng-model>
Related videos on Youtube
Comments
-
Arun P Johny about 2 years
I'm trying to write a directive which make use of isolated scope and ngModel directive.
Problem:
When the model is updated in the directive the value of the caller is not getting updated.HTML:
<test-ng-model ng-model="model" name="myel"></test-ng-model>
Directive:
app.directive( 'testNgModel', [ '$timeout', '$log', function ($timeout, $log) { function link($scope, $element, attrs, ctrl) { var counter1 = 0, counter2 = 0; ctrl.$render = function () { $element.find('.result').text(JSON.stringify(ctrl.$viewValue)) } $element.find('.one').click(function () { if ($scope.$$phase) return; $scope.$apply(function () { var form = angular.isObject(ctrl.$viewValue) ? ctrl.$viewValue : {}; form.counter1 = ++counter1; ctrl.$setViewValue(form); }); }); $element.find('.two').click(function () { if ($scope.$$phase) return; $scope.$apply(function () { var form = angular.isObject(ctrl.$viewValue) ? ctrl.$viewValue : {}; form.counter2 = ++counter2; ctrl.$setViewValue(form); }); }); $scope.$watch(attrs.ngModel, function (current, old) { ctrl.$render() }, true) } return { require: 'ngModel', restrict: 'E', link: link, //if isolated scope is not set it is working fine scope: true, template: '<div><input type="button" class="one" value="One"/><input type="button" class="two" value="Two"/><span class="result"></span></div>', replace: true }; }]);
Demo: Fiddle
If the isolated scope is not set it works fine: fiddle
-
Mark Rajcok almost 11 years
scope: true
does not create an isolate scope, it creates a new child scope that prototypically inherits from the parent scope, hence the reason$parent.model
works. (An isolate scope is created when we use thescope: { ... }
syntax. Here, an new child scope is also created, but it does not prototypically inherit from the parent.) In general, a child scope should be used with ng-model since you are creating a component that needs to interact with other directives (i.e., ng-model). So I suggest you go with your second, working, fiddle. -
Arun P Johny almost 11 years@MarkRajcok that is not an option for me since the directive is more complex and it adds some custom attributes to the scope which will lead to pollution of the parent scope
-
Mark Rajcok almost 11 yearsOk, use
scope: true
, but also use an object, not a primitive:<test-ng-model ng-model="someObj.model" ...>
. fiddle.
-
-
Mark Rajcok almost 11 years
scope: true
doesn't create an isolate scope. -
Wagner Francisco almost 11 yearsGood point. My solution would work anyway, even if the scope is not isolate. But the solution you propose is far better.
-
Arun P Johny almost 11 yearsis it possible to make it work with isolated scope instead of new scope jsfiddle.net/arunpjohny/gbfNY/1
-
Mark Rajcok almost 11 years@ArunPJohny, the parent scope is not getting updated -- notice that the
{{someObj.model | json}}
output is empty. For more about how isolate scopes and ng-model don't mix, see stackoverflow.com/questions/11896732/….