为什么$ viewValue === $ modelValue选择?

时间:2015-02-23 13:58:20

标签: angularjs

http://plnkr.co/edit/iVvvdbvI3it7KrYZW6mK

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.selectModel = '1';
  $scope.inputModel = new Date();
  $scope.testOptions = [
    {key: '1', description: 'text 1'},
    {key: '2', description: 'text 2'},
    {key: '3', description: 'text 3'}
  ];
});

<body ng-controller="MainCtrl">
    <form name="inputForm">
      <strong>how $viewValue works for input</strong><br />
      <input type="date" name="input" ng-model="inputModel"/>
      <div>$viewValue: {{inputForm.input.$viewValue}}</div>
      <div>$modelValue: {{inputForm.input.$modelValue}}</div>
    </form>
    <br /><br /><br />
    <form name="selectForm">
      <strong>how $viewValue works for select</strong><br />
      <select name="select" ng-model="selectModel" ng-options="item.key as item.description for item in testOptions"></select>
      <div>$viewValue: {{selectForm.select.$viewValue}}</div><!--shows '1', i expected 'text 1'-->
      <div>$modelValue: {{selectForm.select.$modelValue}}</div><!--shows '1', as expected-->
    </form>
  </body>

在上面的plunker中,你可以看到$ viewValue对输入与选择的不同含义。

对于输入,$ viewValue是用户看到的字符串,$ modelValue是数据模型。

对于select,$ viewValue和$ modelValue相等,都是数据模型。 这对我没有任何意义。那是为什么?

为了澄清,我的问题是关于select元素,具体来说:$ viewValue来自哪里(似乎总是等于$ modelValue),以及为什么它不是在select元素中显示的实际文本? < / p>

2 个答案:

答案 0 :(得分:1)

$viewValue是浏览器提供的inputElement.value
由于输入类型是Date angular的内置ngModel解析器将解析$viewValue将其转换为日期然后将其分配给模型。
来自AngularJS的代码片段

ctrl.$parsers.push(function(value) {
         if(ctrl.$isEmpty(value)) {
            ctrl.$setValidity(type, true);
            return null;
         }

         if(regexp.test(value)) {
            ctrl.$setValidity(type, true);
            return parseDate(value);
         }

         ctrl.$setValidity(type, false);
         return undefined;
      });

答案 1 :(得分:1)

$viewValue的性质由指令决定。 $render方法将视图值带到屏幕,如果用户可以更改值,则该指令将用户的输入转换为视图值。如何发生完全取决于指令。

$render的默认实施,例如是空的。 input的实现只是设置元素的值:

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

这就是$viewValue等于显示的值的原因。 select的实现更复杂,因为您有很多选项(双关语)。当您使用ng-options时,生成的HTML就像这样:

<option value="0" selected="selected" label="text 1">text 1</option>
<option value="1" label="text 2">text 2</option>
<option value="2" label="text 3">text 3</option>

正如您所看到的,实际值是一个简单的索引,几乎与您的模型无关。此外,selection标记允许多个选择。因此,您有多种不同的可能性来查看视图值。我想让$viewValue等于模型值是最容易的。

FWIW:想象一下使用ng-model但不直接显示值的自定义指令,如自定义滑块。不使用单独的视图值而只是使用模型值非常有意义。