setViewValue in directive on input not updating actual visible input value

41,757

You need to call ngModel.$render() to have the viewvalue change reflected in the input. There is no watch created on $viewValue so that changes are automatically reflected.

   function setAnotherValue() {
        ngModel.$setViewValue("I'm a new value of the model. I've been set using the setViewValue method");
        ngModel.$render();
    }

Plnkr

Default implementation of $render does this:-

 element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);

However you can override and customize your implementation for $render as well..

Share:
41,757
Allisone
Author by

Allisone

Updated on March 08, 2020

Comments

  • Allisone
    Allisone over 4 years

    I've been fighting with this for almost two days. I hope you guys can help me.

    Summary:
    I have problems setting the view value of some input fields programatically.
    I have a form with inputs whose values are saved before the form is removed (multiple elements and multiple forms possible, user might close a form, and reopen later). On reopening the form I want to restore the previous view values (main reason is to get back also the invalid view values which were not saved in the model). This doesn't work.

    If I call ctrl.$setViewValue(previousValue) I get the model (visibly) updated (if valid), the view values of the formControl (while debugging in console) are changed too, but I don't get them actually rendered in the input fields. I don't understand why :(

    I reduced the problem to this fiddle:
    http://jsfiddle.net/g0mjk750/1/

    javascript

    var app = angular.module('App', [])
    
        function Controller($scope) {
            $scope.form = {
                userContent: 'initial content'
            }
        }
    app.controller('Controller', Controller);
    app.directive('resetOnBlur', function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, element, attrs, ngModel) {
                element.bind('blur', function () {
                    console.log(ngModel);
                    scope.$apply(setAnotherValue);
                });
                function setAnotherValue() {
                    ngModel.$setViewValue("I'm a new value of the model. I've been set using the setViewValue method");
                }
            }
        };
    });
    

    Html

    <form name="myForm" ng-app="App" ng-controller="Controller" class="form">
        Text: {{form.userContent}}
        <hr />
        If you remove the text, "Required!" will be displayed.<br/>
        If you change the input value, the text will update.<br/>
        If you blur, the text will update, but the (visible) input value not.
        <hr />
        <input class="input" type="text" ng-model="form.userContent" name="userContent" reset-on-blur required></textarea>
        <span ng-show="myForm.userContent.$error.required">Required!</span>
    </form>
    

    I hope you guys can explain to me why this doesn't work and how to fix this...