Какая разница между ngModel. $ModelValue и ngModel. $ViewValue

У меня есть следующая директива ckEditor. Внизу два варианта, которые я видел из примеров того, как установить данные в редакторе:

app.directive('ckEditor', [function () {
    return {
        require: '?ngModel',
        link: function ($scope, elm, attr, ngModel) {

            var ck = null;
            var config = attr.editorSize;
            if (config == 'wide') {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-wide.js' });
            } else {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-narrow.js' });
            }


            function updateModel() {
                $scope.$apply(function () {
                    ngModel.$setViewValue(ck.getData());
                });
            }

            $scope.$on('modalObjectSet', function (e, modalData) {
                // force a call to render
                ngModel.$render();
            });

            ck.on('change', updateModel);
            ck.on('mode', updateModel);
            ck.on('key', updateModel);
            ck.on('dataReady', updateModel);

            ck.on('instanceReady', function () {
                ngModel.$render();
            });

            ck.on('insertElement', function () {
                setTimeout(function () {
                    $scope.$apply(function () {
                        ngModel.$setViewValue(ck.getData());
                    });
                }, 1000);
            });

            ngModel.$render = function (value) {
                ck.setData(ngModel.$modelValue);
            };

            ngModel.$render = function (value) {
                ck.setData(ngModel.$viewValue);
            };
        }
    };
}])

Может кто-нибудь сказать мне, в чем разница между:

ck.setData(ngModel.$modelValue);
ck.setData(ngModel.$viewValue);

И что я должен использовать. Я посмотрел документацию angular и сказал:

$viewValue

Actual string value in the view.

$modelValue

The value in the model, that the control is bound to.

Я не знаю, что имел в виду автор, когда писал это в документе: - (

Ответ 1

Вы смотрите на правильную документацию, но может быть, вы немного запутались. $modelValue и $viewValue имеют одно отличие. Это:

Как вы уже отметили выше:

$viewValue: Фактическое значение строки (или объекта) в представлении.
$modelValue: Значение в модели, к которой привязан элемент управления.

Я собираюсь предположить, что ваш ngModel ссылается на элемент <input />...? Итак, ваш <input> имеет строковое значение, которое он отображает для пользователя, верно? Но фактической моделью может быть какая-то другая версия этой строки. Например, на входе может отображаться строка '200', но <input type="number"> (например) фактически будет содержать модельное значение 200 как целое число. Таким образом, строковое представление, которое вы "просматриваете" в <input>, это ngModel.$viewValue, а числовое представление будет ngModel.$modelValue.

Другим примером может быть <input type="date">, где $viewValue будет чем-то вроде Jan 01, 2000, а $modelValue будет фактическим javascript Date объектом, который представляет эту строку даты. Это имеет смысл?

Надеюсь, что ответ на ваш вопрос.

Ответ 2

Вы можете видеть такие вещи:

  • $modelValue - ваш внешний API, то есть что-то, что отображается на вашем контроллере.
  • $viewValue - это ваш внутренний API, вы должны использовать его только внутренне.

При редактировании $viewValue метод рендеринга не будет вызываться, потому что это "визуализированная модель". Вам нужно будет сделать это вручную, тогда как метод рендеринга будет вызываться автоматически при модификациях $modelValue.

Однако информация останется неизменной благодаря $formatters и $parsers:

  • Если вы измените $viewValue, $parsers переведет его обратно $modelValue.
  • Если вы измените $modelValue, $formatters будет преобразуйте его в $viewValue.

Ответ 3

Angular должен отслеживать два представления данных ngModel - там данные, которые видит DOM (браузер), а затем там Angular обработано представление этих значений. $viewValue - значение стороны DOM. Так, например, в <input> $viewValue пользователь вводит свой браузер.

Как только кто-то что-то набирает в <input>, тогда $viewValue обрабатывается $parsers и превращается в представление Angular значения, которое называется $modelView.

Итак, вы можете думать о $modelView как Angular обработанной версии значения, значение, которое вы видите в модели, а $viewValue - это необработанная версия.

Чтобы сделать следующий шаг, представьте, что мы делаем что-то, что меняет $modelView. Angular видит это изменение и вызывает $formatters для создания обновленного $viewValue (на основе нового $modelView) для отправки в DOM.