Яка різниця між 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);

І який я повинен використовувати. Я подивився кутову документацію і там написано:

$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.. Отже, так.
тенісгент

7
Ще одна примітка. Коли <input type="text">значення порожнє, $modelValueвластивість є undefined, тоді $viewValueяк ''порожній рядок. Це може змінити ситуацію, якщо ви нюхаєте "довжину", $modelValueяка не буде працювати, але $viewValueбуде.
BradGreens

8
Це $viewValueне завжди рядок. Це рядок для поточних директив Angular core, але це може бути примітив або об’єкт у ваших користувацьких елементах керування. Хорошим прикладом є <input file="type">компонент, де viewValue містить FileListоб'єкт із файлами, прикріпленими користувачем. Документи Angular з цього приводу заплутані і їх слід оновити.
demisx

4
Крім того, якщо введення недійсне, $ modelValue не буде встановлено. Тобто, якщо у вас є <input ng-minlength = "8" ...> і ви вводите лише 5 символів, $ viewValue покаже ці 5 символів, але $ modelValue не буде існувати.
honkskillet

27

Ви можете побачити такі речі:

  • $modelValue це ваш зовнішній API, тобто щось, що впливає на ваш контролер.
  • $viewValue це ваш внутрішній API, ви повинні використовувати його лише внутрішньо.

Під час редагування $viewValueметод візуалізації не буде викликаний, оскільки це "візуалізована модель". Вам доведеться робити це вручну, тоді як метод візуалізації буде викликаний автоматично при $modelValueвнесенні змін.

Однак інформація залишатиметься послідовною завдяки $formatters та $parsers:

  • Якщо зміниш $viewValue , $parsersперекладе його назад на $modelValue.
  • Якщо змінити $modelValue, $formattersперетворить його на $viewValue.

При редагуванні $ viewValue метод візуалізації не буде викликаний. Якщо ви зміните $ viewValue, $ парсери переведуть його назад у $ modelValue.means $ modelvalue change.and метод візуалізації буде викликаний автоматично при $ modelValue modifications.so опосередковано, коли $ viewValue змінюється, викликається метод render. є це ?
Мукунд Кумар,

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 бачить цю зміну і закликає $ $viewValue-форматори створити оновлену (на основі нової $ modelValue), яка буде надіслана до DOM.


ви маєте на увазі $ modelValue або $ modelView ?? Якщо $ modelValue, будь ласка, виправте помилку.
Планктон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.