我有一个处理文件上传的指令。该指令使用'controller'和'controllerAs'作为动态控制器,在'link'函数中,它触发在相关动态控制器中执行的回调。
问题是在控制器中执行回调时,'this'未定义。如何在控制器中设置imageUrl?
指令:
.directive('attachable', function(FileUploader) {
return {
restrict : 'E',
transclude : true,
templateUrl : 'template.html',
scope : {},
controller : '@',
controllerAs: 'uploadCtrl',
name : 'controller',
link: function(scope, element, attrs) {
var controller = scope.uploadCtrl;
var uploader = scope.uploader = new FileUploader({
url: controller.uploadUrl
});
// callbacks
uploader.onAfterAddingFile = function(item) {
controller.onAfterAddSuccess();
};
}
};
});
控制器:
angular.module('core').controller('controller', ['$window', function($window){
this.onAfterAddSuccess = function(item){
if ($window.FileReader) {
var fileReader = new FileReader();
fileReader.readAsDataURL(item._file);
fileReader.onload = function (fileReaderEvent) {
$timeout(function () {
this.imageURL = fileReaderEvent.target.result; // <- this is undefined
}, 0);
};
}
};
}]);
HTML:
<attachable controller="controller" ></attachable>
修改
ste2425的答案解决了'未定义'的错误,但为什么 imageURL的新值在我的控制器外不可用,即视图?
更新控制器:
...
fileReader.onload = function (fileReaderEvent) {
this.imageURL = '';
$timeout(function(){
this.imageURL = fileReaderEvent.target.result;
}.bind(this), 1);
};
...
HTML:
imageURL: {{ imageURL }} <- this is still ''
<attachable controller="controller" ></attachable>
答案 0 :(得分:0)
Angular会将this
的{{1}}设置为窗口。
您有几种选择。之一:
绑定你的函数的这个上下文:
$timeout
或使用角度v1.4.1或更高
this.test = 'hiya';
$timeout(function(){
console.log('this WONT fail', this.test);
}.bind(this), 1);
答案 1 :(得分:0)
这是JavaScript闭包的副作用。解决此问题的最常用,直接的方法是声明一个表示控制器的常量变量,该变量可以在闭包内引用,而不会被闭包本身隐藏。
angular.module('core').controller('controller', ['$window', function($window){
var vm=this; //constant reference to controller
....
fileReader.onload = function (fileReaderEvent) {
vm.imageURL = '';
$timeout(function(){
vm.imageURL = fileReaderEvent.target.result;
}, 0);
};
....