javascript - angularjs - 指令中的动态回调

标签 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]);
                });
            }
        };
    });

指令模板

<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;' 
           />
    &nbsp;
    <span class='label label-info'>{{file.name}}</span>
</span>

我在其中使用指令的一段 html 文件

<xxx-file-uploader on-change="loadFile(field.name)" ></xxx-file-uploader>

和我的 Controller 的相关部分

$scope.loadFile = function(fieldName) {
    return function(file) {
        // do things with both fieldName and file...
    };
};

这段代码应该只自定义文件类型输入的外观,并在上传文件时执行回调。

我的问题来自于目前我需要使用为每个 fileUploader 动态构建的更改回调。如您所见,回调是使用链接时已知的参数 fieldName 和“执行时”已知的参数文件构建的。

通过这段代码,我得到了 AngularJS“错误:达到 10 次 $digest() 迭代。堕胎!”因为(我认为)该函数一次又一次地生成并且摘要不匹配。

一个穷人的解决方案是将 fieldName 作为另一个范围变量传递。另一个可能是将函数作为字符串 (@) 传递,并在我需要时构建回调。

关于如何在不更改其接口(interface)的情况下使该指令工作的任何建议?我对 angularjs 指令很陌生(这是我的第一个指令!)所以如果您发现代码中有任何错误,请指出。

谢谢。

第一次编辑:

我尝试按照建议更改指令的范围

scope: {
    onChange: '='
},

scope: {
    onChange: '&'
},

我改变了回调调用

scope.onChange(input.files[0]);

scope.onChange()(input.files[0]);

现在可以了,但我对结果并不完全满意。

看起来需要调用 onChange 函数来获取我的“真实”回调。在这种情况下,有没有办法让它隐式执行?

我的意思是如果我写

<xxx-file-uploader on-change="loadFile(field.name)" ></xxx-file-uploader>

应该理解执行函数

如果我写

<xxx-file-uploader on-change="doSomething" ></xxx-file-uploader>

它应该认识到 doSomething 是我希望它执行的“真正的”回调(使用文件参数)。

最佳答案

您使用 onChange: '=' 的方式和函数不正确。以下解决方案确实稍微更改了指令的接口(interface),但我认为将 onChange 重命名为 onChangeFactory 更好地反射(reflect)了其预期用途。该名称可以保留为 onChange,但是如果您不介意这种小的不一致的话。


loadFile() 本身传递为:

<xxx-file-uploader on-change-factory="loadFile(fname)" ></xxx-file-uploader>

修改指令以使用函数绑定(bind):

scope: {
    onChangeFactory: "&"
}

调用工厂并在 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
                }
            });
        }

请注意从指令内部调用 onChangeFactory() 的方式!我想会有一些差距(例如文件名),但我相信这是一个很好的起点。

关于javascript - angularjs - 指令中的动态回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19831933/

相关文章:

php - 使用 jquery 将多个复选框的值添加到数据库中的同一行

javascript - 对话框中的 jquery 火灾事件

javascript - 使用字典将返回的状态映射到选择下拉列表以进行过滤,会产生我试图删除的重复项并将唯一键附加到

javascript - 在 IE8 的 iFrame 中运行 AngularJS 应用程序的空白页面

javascript - 表单提交预防技术不起作用

php - mysql查询安全限制

javascript - AngularJS : the binding isn't applied when calling a service on an event

javascript - 如何在 ng-if 中传递 ng-repeat 变量?

javascript - Internet Explorer 11 中的 FormData.entries()?

javascript - 如何在延迟后调用owlCarousel函数?