我有一个类似下面的指令。应该从<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: {},
}
});
最佳答案
由于this change,此问题自1.2.0起已修复:
修复了隔离范围到处泄漏到同一元素上其他指令的问题。
现在,隔离范围仅可用于请求隔离范围及其模板的isolate指令。
在1.2.0之前,如果某个元素上的任何指令请求了隔离范围,则该元素上的所有指令都共享该范围。
在您的情况下,这导致input
指令使用您为指令请求的隔离范围,而不是html <p>Filename is: {{ file.name }}</p>
所在的父范围。因此file
是undefined
,因为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