95

我有以下 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.

我不知道作者在文档中写这篇文章时的意思:-(

4

3 回答 3

153

您正在查看正确的文档,但可能只是您有点困惑。$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那有意义吗?

我希望这能回答你的问题。

于 2013-10-15T15:01:30.797 回答
27

你可以看到这样的事情:

  • $modelValue是你的外部 API,也就是说,暴露给你的控制器的东西。
  • $viewValue是您的内部 API,您应该只在内部使用它。

编辑时$viewValue,不会调用 render 方法,因为它是“渲染模型”。您必须手动完成,而渲染方法将在$modelValue修改时自动调用。

但是,由于$formatters和,信息将保持一致$parsers

  • 如果你改变了$viewValue$parsers就会把它翻译回来 $modelValue
  • 如果更改$modelValue$formatters将其转换为$viewValue.
于 2013-10-15T15:27:51.837 回答
18

Angular 必须跟踪 ngModel 数据的两个视图——一个是 DOM(浏览器)看到的数据,另一个是 Angular 对这些值的处理表示。是$viewValueDOM 端值。因此,例如,用户在浏览器中输入的内容 <input>$viewValue

一旦有人输入了一些东西,<input>那么$viewValue$parsers 就会处理并变成 Angular 的值视图,称为$modelValue.

所以你可以认为$modelValue是 Angular 的值的处理版本,你在模型中看到的值,$viewValue而是原始版本。

为了更进一步,想象我们做一些改变$modelValue. Angular 看到了这种变化并调用 $formatters 来创建一个更新的$viewValue(基于新的 $modelValue)以发送到 DOM。

于 2013-10-15T15:24:21.993 回答