为什么ngModel。$ setViewValue没有效果?

时间:2013-12-06 02:21:41

标签: javascript angularjs angularjs-directive

我有一个如下指令。它应该从<input type=file>加载文件并将其设置为提供的ng-model。它也有一些自定义验证只是偶然的问题。它也是on 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 个答案:

答案 0 :(得分:0)

由于this change

,因此从1.2.0开始修复
  

修复了隔离范围泄漏到同一元素上的其他指令的问题。

     

隔离范围现在仅适用于请求它的isolate指令及其模板。

在1.2.0之前,如果某个元素的任何指令请求隔离范围,则该元素上的所有指令都共享该范围。

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

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

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

您会在this updated plunker中看到在1.2.0之前的代码中解决了这个问题。

最好的解决办法是转向1.2.0。使用1.2.0,您的隔离范围只会影响您的指令,而不会影响'input'指令,因此一切都按预期工作in this plunker