我来自更严格的语言,如Java,C#,C ++,并且一直使用此代码将文件读入textarea而不了解它是如何工作的,因为时间问题。现在我正在尝试学习指令,所以我可以理解这个指令,但是我很难理解这段代码的一部分。
这是我希望调用的控制器功能。 fileContent只是一串文本:
self.displayFileContent = function(contents) {
self.fileContent = contents;
};
这是read file指令的实现。我期待调用是displayFileContentFn(fileContents)
,但为什么调用具有完全不同的参数(和不同数量的参数)的函数?这里是{'contents:filecontents}一个javascript对象吗?
scope: false,
link: function(scope, element, attrs) {
element.bind('change', function(e) {
var displayFileContentFn = $parse(attrs.onFileChange);
var reader = new FileReader();
reader.onload = function() {
var fileContents = reader.result;
scope.$apply(function() {
displayFileContentFn(scope, {
'contents' : fileContents
});
});
};
reader.readAsText(element[0].files[0]);
});
}
答案 0 :(得分:2)
这与angular&#s; $ parse服务有关。
如果你绑定了on-file-change属性,如:
on-file-change='displayFileContent(content)'
displayFileContenFn由:
定义var displayFileContentFn = $parse(attrs.onFileChange);
实际上是给出类似的东西(真正的代码在这里复杂得多,我只是简化它以使其易于理解):
var displayFileContentFn = function(scope,parameters){
var contents = parameters['contents'];
scope.displayFileContent(contents);
}
所以这里
displayFileContentFn(scope, {
'contents' : fileContents
});
表示使用scope
执行displayFileContent
(因为我们将它绑定到on-file-change属性),将fileContents作为contents
参数传递(我们将其声明为在属性中作为第一个参数)。
这样,当读者完成阅读时,fileContents读取将作为displayFileContent
传递给contents
函数。
答案 1 :(得分:0)
要了解这里发生的事情,您必须了解角度生命周期的工作原理。
基本上,您向$scope.$apply
提供表达式而非函数。该表达式使用$scope.$eval
执行,允许针对提供的scope
计算表达式。 (在这种情况下,scope
由指令定义)在计算表达式之后,处理任何异常处理,然后可以触发任何监视。
$ apply的伪代码()
function $apply(expr) {
try {
return $eval(expr);
} catch (e) {
$exceptionHandler(e);
} finally {
$root.$digest();
}
}
对于您的功能,如果您的HTML为on-file-change='displayFileContent(contents)'
,$scope.$apply()
正在接受
displayFileContentFn(scope, {
'contents' : fileContents
});
并返回displayFileContent(fileContents)
,其中来自HTML的displayFileContentFn == onFileChange
和来自JavaScript函数的contents == fileContents
。然后执行此操作。