В чем разница между ngModel. $ ModelValue и ngModel. $ ViewValue

94

У меня есть следующая директива 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.

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

Саманта Джей Ти Стар
источник

Ответы:

151

Вы смотрите правильную документацию, но, возможно, вы немного запутались. У $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будет фактический Dateобъект javascript , представляющий эту строку даты. Имеет ли это смысл?

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

теннисист
источник
В общем, $viewValueвсегда ли это строка?
cdmckay
7
Как говорят документы: $viewValue: Actual string value in the view.. Так да.
Tennisgent
7
Еще одно замечание. Когда <input type="text">значение пусто, то $modelValueсвойство undefined, в то время как $viewValueэто ''пустая строка. Это может иметь значение, если вы нюхаете «длину», $modelValueкоторая не сработает, но $viewValueбудет.
BradGreens 07
8
$viewValueНе всегда является строкой. Это строка для текущих директив ядра Angular, но это может быть примитив или объект в ваших пользовательских элементах управления. Хорошим примером является <input file="type">компонент, в котором viewValue содержит FileListобъект с прикрепленными пользователем файлами. Документы по Angular сейчас сбивают с толку и должны быть обновлены.
demisx
4
Также нет, если ввод неверен, $ modelValue не будет установлен. То есть, если у вас есть <input ng-minlength = "8" ...>, и вы вводите всего 5 символов, $ viewValue покажет эти 5 символов, но $ modelValue не будет существовать.
хонскиллет
27

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

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

При редактировании $viewValueметод рендеринга не вызывается, потому что это «рендеринговая модель». Вам придется делать это вручную, тогда как метод рендеринга будет вызываться автоматически при $modelValueвнесении изменений.

Тем не менее, информация будет оставаться последовательной, благодаря $formattersи $parsers:

  • Если поменять $viewValue, $parsersпереведу обратно на $modelValue.
  • Если вы измените $modelValue, $formattersпреобразует его в $viewValue.
Вианни Дюпой де Гитар
источник
При редактировании $ viewValue метод рендеринга не вызывается. Если вы измените $ viewValue, $ parsers переведут его обратно в $ modelValue. Означает изменение $ modelvalue. И метод рендеринга будет вызываться автоматически при изменениях $ modelValue. Поэтому косвенно, при изменении $ viewValue вызывается метод рендеринга. это ?
Мукунд Кумар
1
Чтобы понять, как это работает, нужно разобраться в конвейере двусторонней привязки Angular ngModel. При обновлении с $viewValueпомощью setViewValue(viewValue)метода включаются парсеры / валидаторы (если есть) и анализируют это viewValueзначение в modelValue, проверяют его, записывают в область видимости и затем запускают viewChangeListeners. При следующем запуске дайджеста значение модели извлекается из области видимости и сравнивается с $ modelValue в контроллере: github.com/angular/angular.js/blob/master/src/ng/directive/… . Если они равны (а в вашем сценарии они будут равны), то он вернется.
demisx
18

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

После того, как кто - то типы что - то в <input>то $viewValueобрабатываются $ анализаторов и превратился в поле зрения ANGULAR о стоимости , которая называется $modelValue.

Таким образом, вы можете представить $modelValueсебя обработанной версией значения angular, значением, которое вы видите в модели, а $viewValueэто необработанная версия.

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

КаякДэйв
источник
Вы имеете в виду $ modelValue или $ modelView ?? Если $ modelValue, пожалуйста, исправьте опечатку.
Plankton