Arun P Johny
Arun P Johny

Reputation: 388316

Directive with isolated scope and ng-model

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

Upvotes: 25

Views: 18276

Answers (2)

Mark Rajcok
Mark Rajcok

Reputation: 364677

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" ...>

fiddle

Upvotes: 13

Wagner Francisco
Wagner Francisco

Reputation: 2200

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>

Upvotes: 7

Related Questions