角度指令范围未定义

时间:2015-06-05 20:15:45

标签: angularjs angularjs-directive angularjs-scope

我使用指令解析xls文件并通过作用域将数据传递给按钮。问题是在链接函数中我绑定到元素更改事件并调用解析xls文件的函数,但是在handleFile函数中未定义范围,因此我无法将数据传递给按钮。将数据输入按钮的正确方法是什么?

angular.module('fileReaderModule')
.directive('xlsReader', function(){

return {
    scope: {
        search: "&"
    },
    link: function(scope, e, attr) {
        e.bind('change', handleFile);
    },
    template: '<input type="file" ng-model="xlsFile"><button ng-click="search({stuff: scope.stuff})">Search</button>'
}

function handleFile(scope, e) {
    var files = e.target.files;
    var i,f;
    for (i = 0, f = files[i]; i != files.length; ++i) {
        var reader = new FileReader();
        var name = f.name;
        reader.onload = function(e) {
            var data = e.target.result;

            var workbook = XLSX.read(data, {type: 'binary'});
            scope.stuff = workbook.Strings; // scope not available here
            /* DO SOMETHING WITH workbook HERE */
            var result = {};
            workbook.SheetNames.forEach(function(sheetName) {
                var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
                if(roa.length > 0){
                    result[sheetName] = roa;
                }
            });
        };
        reader.readAsBinaryString(f);
    } 
}
})

1 个答案:

答案 0 :(得分:2)

在模板内部,您不需要使用scope

替换它:

template: '<input type="file" ng-model="xlsFile"><button ng-click="search({stuff: scope.stuff})">Search</button>'

用这个:

template: '<input type="file" ng-model="xlsFile"><button ng-click="search({stuff: stuff})">Search</button>'

您还应该声明您的功能:

angular.module('fileReaderModule')
.directive('xlsReader', function($timeout){

    return {
        scope: {
            search: "&"
        },
        link: function(scope, e, attr) {
            e.bind('change', scope.handleFile);

            scope.handleFile(e) {
              var files = e.target.files;
              var i,f;
              for (i = 0, f = files[i]; i != files.length; ++i) {
                var reader = new FileReader();
                var name = f.name;
                reader.onload = function(e) {
                    //Async code, need $timeout call so angular runs a digest cycle and updates the bindings
                    $timeout(function(){
                        var data = e.target.result;

                        var workbook = XLSX.read(data, {type: 'binary'});
                        scope.stuff = workbook.Strings;
                        var result = {};
                        workbook.SheetNames.forEach(function(sheetName) {
                            var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
                            if(roa.length > 0){
                                result[sheetName] = roa;
                            }
                        });
                    });
                };
                reader.readAsBinaryString(f);
            }
        }
    },
    template: '<input type="file" ng-model="xlsFile"><button ng-click="search({stuff: stuff})">Search</button>'
});