web-dev-qa-db-ja.com

入力のディレクティブのsetViewValueが実際の表示可能な入力値を更新しない

私はこれとほぼ2日間戦ってきました。皆さんが私を助けてくれることを願っています。

概要:
一部の入力フィールドの表示値をプログラムで設定するのに問題があります。
フォームが削除される前に値が保存される入力を持つフォームがあります(複数の要素と複数のフォームが可能です。ユーザーはフォームを閉じて、後で再び開くことができます)。フォームを再度開いたときに、以前のビュー値を復元したい(主な理由は、モデルに保存されていない無効なビュー値も取得することです)。これは機能しません。

Ctrl。$ setViewValue(previousValue)を呼び出すと、モデルが(視覚的に)更新されます(有効な場合)。formControlのビュー値(コンソールでのデバッグ中)も変更されますが、実際にレンダリングされません。入力フィールド。理由がわかりません:(

このフィドルに問題を減らしました:
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>

なぜこれがうまくいかないのか、これを修正する方法を説明してくれることを願っています...

25
Allisone

ngModel.$render() を呼び出して、viewvalueの変更を入力に反映させる必要があります。 $viewValueにはウォッチが作成されていないため、変更は自動的に反映されます。

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

Plnkr

$renderのデフォルトの実装はこれを行います:-

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

ただし、$renderの実装もオーバーライドおよびカスタマイズできます。

78
PSL