为什么ngModel$setViewValue无效

Why does ngModel.$setViewValue have no effect?

本文关键字:无效 setViewValue ngModel 为什么      更新时间:2024-04-06

我有一个指令,如下所示。它应该从<input type=file>加载一个文件,并将其设置为提供的ng-model。它还得到了一些自定义验证,这只是我的问题附带的。它也在plunkr上。

问题是ngModel根本就没有设置好。它总是undefined。为什么?

app.directive('fileInput', function () {
  var link = function (scope, element, attrs, ngModel) {
    var VALIDTYPES = ['text/csv', 'text/directory', 'text/vcard'];
    var updateModel = function () {
      var file = element[0].files[0];
      if (file) {
        scope.$apply(function () {
          if (VALIDTYPES.indexOf(file.type) >= 0) {
            ngModel.$setValidity("mimetype", true);
            ngModel.$setViewValue(file);
          } else {
            ngModel.$setValidity("mimetype", false);
            alert("Sorry, can only accept VCF and CSV files.");
          }
        })
      }
    };
    element.bind('change', updateModel);
  };
  return {
    restrict: 'A',
    require: 'ngModel',
    template: "<input type='file'>",
    replace: true,
    link: link,
    scope: {},
  }
});

由于此更改,从1.2.0起已修复:

修复了隔离作用域到处泄漏到同一元素上的其他指令中的问题。

隔离作用域现在仅可用于请求它的隔离指令及其模板。

在1.2.0之前,如果某个元素上的任何指令请求了一个隔离作用域,那么该元素上的所有指令都共享该作用域。

在您的情况下,这导致input指令使用您为指令请求的隔离作用域,而不是html <p>Filename is: {{ file.name }}</p>所在的父作用域。因此fileundefined,因为file在子作用域上

您可以在1.2.0之前的操作中看到,通过使用$setViewValue:下面的这一行将$viewValue复制到父作用域

ngModel.$setViewValue(file);  
scope.$parent.file = ngModel.$viewValue;

你会在这个更新的plunker中看到,它在1.2.0之前的代码中修复了这个问题。

不过,最好的解决方案是转到1.2.0。在1.2.0中,您的隔离作用域只会影响您的指令,而不会影响"输入"指令,因此在这个plunker 中一切都按预期运行