hea*_*low 4 javascript jquery angularjs
我正在尝试用angularjs创建一个指令,但我发现了一个问题.
这是指令的js代码
angular.module('xxxFileUploader', [])
.directive('xxxFileUploader', function() {
return {
restrict: 'E',
templateUrl: 'fileUploader.html',
scope: {
onChange: '='
},
link: function(scope, element, attrs) {
element.find('input[type="file"]').change(function() {
var input = this;
if (input.files && input.files[0]) {
scope.file = input.files[0];
scope.onChange(input.files[0]);
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
指令模板
<span style="position:relative;">
<a class='btn btn-primary' href='javascript:;'>
Choose File...
</a>
<input type="file"
name="{{field.name}}"
style='position:absolute;z-index:2;top:0;left:0;filter: alpha(opacity=0);opacity:0;background-color:transparent;color:transparent;'
/>
<span class='label label-info'>{{file.name}}</span>
</span>
Run Code Online (Sandbox Code Playgroud)
我使用该指令的一段html文件
<xxx-file-uploader on-change="loadFile(field.name)" ></xxx-file-uploader>
Run Code Online (Sandbox Code Playgroud)
和我的控制器的相关部分
$scope.loadFile = function(fieldName) {
return function(file) {
// do things with both fieldName and file...
};
};
Run Code Online (Sandbox Code Playgroud)
此代码应该只定制类型文件的输入外观,并在上载文件时执行回调.
我的问题来自于此刻我需要使用为每个fileUploader动态构建的更改回调.正如您所看到的,回调是使用在链接时已知的参数fieldName和在"执行时"已知的参数文件构建的.
使用此代码,我得到了AngularJS"Error:10 $ digest()迭代次数.中止!"因为(我认为)一次又一次地生成函数,并且摘要不匹配.
穷人解决方案是将fieldName作为另一个范围变量传递.另一个可能是将函数作为字符串(@)传递并在需要时构建回调.
关于如何在不改变界面的情况下使该指令工作的任何建议?我对angularjs指令很新(这是我的第一个!)所以如果你看到代码中有任何错误,请指出它.
谢谢.
首先编辑:
正如我所建议的那样,我试图改变指令的范围
scope: {
onChange: '='
},
Run Code Online (Sandbox Code Playgroud)
至
scope: {
onChange: '&'
},
Run Code Online (Sandbox Code Playgroud)
我改变了回拨电话
scope.onChange(input.files[0]);
Run Code Online (Sandbox Code Playgroud)
至
scope.onChange()(input.files[0]);
Run Code Online (Sandbox Code Playgroud)
现在它有效,但我对结果并不完全满意.
看起来需要调用onChange函数来获取我的"真实"回调.在这种情况下有没有办法隐式执行它?
我的意思是如果我写的话
<xxx-file-uploader on-change="loadFile(field.name)" ></xxx-file-uploader>
Run Code Online (Sandbox Code Playgroud)
它应该理解执行该功能
如果相反我写
<xxx-file-uploader on-change="doSomething" ></xxx-file-uploader>
Run Code Online (Sandbox Code Playgroud)
它应该认识到doSomething是我希望它执行的"真正的"回调(使用file参数).
您使用的方式onChange: '='和功能不正确.以下解决方案可以稍微改变指令的接口,但我认为重命名onChange可以onChangeFactory更好地反映其预期用途.onChange但是,如果您不介意小的不一致,则可以保留该名称.
将loadFile()自己传递给:
<xxx-file-uploader on-change-factory="loadFile(fname)" ></xxx-file-uploader>
Run Code Online (Sandbox Code Playgroud)
修改指令以使用函数绑定:
scope: {
onChangeFactory: "&"
}
Run Code Online (Sandbox Code Playgroud)
Call the factory and get the actual callback in link():
link: function(scope, element, attrs) {
// HOW ARE YOU GETTING FIELDNAME???
var onChange = scope.onChangeFactory({fname: FIELDNAME});
element.find('input[type="file"]').change(function() {
var input = this;
if (input.files && input.files[0]) {
scope.file = input.files[0];
onChange(input.files[0]); // <--- NOTE CHANGE HERE TOO
}
});
}
Run Code Online (Sandbox Code Playgroud)
Do pay attention on the way of calling onChangeFactory() from inside the directive! I guess there will be some gaps (e.g. the filename), but I believe this is a good starting point.
| 归档时间: |
|
| 查看次数: |
8173 次 |
| 最近记录: |