【问题标题】:why $viewValue === $modelValue on select?为什么选择 $viewValue === $modelValue?
【发布时间】:2017-11-17 05:42:57
【问题描述】:

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 对于 input 和 select 的不同含义。

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

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

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

【问题讨论】:

    标签: angularjs


    【解决方案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 但不直接显示值的自定义指令,如自定义滑块。不使用单独的视图值而仅使用模型值是非常有意义的。

    【讨论】:

      【解决方案2】:

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

      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;
            });
      

      【讨论】:

      • 在谈到
      • 使用 ng-options 提供的 select 呈现为:&lt;select&gt; &lt;option value="0"&gt;text 1&lt;/option&gt; &lt;option value="1"&gt;text 2&lt;/option&gt; &lt;/select&gt; 在这种情况下,select 的值将是 0/1/2 ...因此 $viewValue 打印为索引数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 2014-01-19
      • 1970-01-01
      相关资源
      最近更新 更多