javascript - AngularJS 指令回调函数

标签 javascript angularjs

所以我有一个指令,它接受回调函数作为参数以及其他一些选项。 这是指令:

.directive('csvReader', [function () {

    // Function to convert to JSON
    var convertToJSON = function (content) {

        // Declare our variables
        var lines = content.csv.split('\n'),
            headers = lines[0].split(content.separator),
            columnCount = lines[0].split(content.separator).length,
            results = [];

        // For each row
        for (var i = 1; i < lines.length; i++) {

            // Declare an object
            var obj = {};

            // Get our current line
            var line = lines[i].split(new RegExp(content.separator + '(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)'));

            // For each header
            for (var j = 0; j < headers.length; j++) {

                // Populate our object
                obj[headers[j]] = line[j];
            }

            // Push our object to our result array
            results.push(obj);
        }

        // Return our array
        return results;
    };

    return {
        restrict: 'A',
        scope: {
            results: '=',
            separator: '=',
            complete: '&'
        },
        link: function (scope, element, attrs) {

            // Create our data model
            var data = {
                csv: null,
                separator: scope.separator || ','
            };

            // When the file input changes
            element.on('change', function (e) {

                // Get our files
                var files = e.target.files;

                // If we have some files
                if (files && files.length) {

                    // Create our fileReader and get our file
                    var reader = new FileReader();
                    var file = (e.srcElement || e.target).files[0];

                    // Once the fileReader has loaded
                    reader.onload = function (e) {

                        // Get the contents of the reader
                        var contents = e.target.result;

                        // Set our contents to our data model
                        data.csv = contents;

                        // Apply to the scope
                        scope.$apply(function () {

                            // Our data after it has been converted to JSON
                            scope.results = convertToJSON(data);

                            // If we have a callback function
                            if (scope.complete) {

                                // Execute our callback
                                scope.complete(scope.results);
                            }
                        });
                    };

                    // Read our file contents
                    reader.readAsText(file);
                }
            });
        }
    };
}])

如您所见,当 CSV 文件转换为 JSON 时,将调用完整的回调函数。在我看来,我有一些 HTML,如下所示:

<div class="portlet light" ng-if="controller.results.length && !controller.import.error">
    <div class="portlet-title">

        <div class="caption caption-md">
            <span class="caption-subject font-green-haze bold uppercase">Collections to import</span>
        </div>

        <div class="inputs">
            <div class="portlet-input input-inline input-small">
                <div class="input-icon right">
                    <i class="icon-magnifier"></i>
                    <input type="text" class="form-control form-control-solid" placeholder="search..." ng-model="controller.filter">
                </div>
            </div>
        </div>

        <div class="actions">
            <div class="btn-group btn-group-devided" data-toggle="buttons">
                <label class="btn btn-transparent grey-salsa btn-circle btn-sm" ng-repeat="size in controller.pageSizes" ng-class="{ active: controller.pageSize === size }">
                    <input type="radio" name="options" class="toggle" ng-model="controller.pageSize" ng-change="controller.pageSize = size"> {{ size }}
                </label>
            </div>
        </div>

    </div>
    <div class="portlet-body">

        <table class="table table-hover table-light">
            <thead>
                <tr class="uppercase">
                    <th>
                        <a href="" ng-click="controller.predicate = 'reference'; controller.reverse = !controller.reverse">Reference</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'customerReference'; controller.reverse = !controller.reverse">Customer Reference</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'customerName'; controller.reverse = !controller.reverse">Name</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'customerBusinessName'; controller.reverse = !controller.reverse">Company</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'supplierName'; controller.reverse = !controller.reverse">Supplier</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'collectionCode'; controller.reverse = !controller.reverse">Code</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'status'; controller.reverse = !controller.reverse">Status</a>
                    </th>
                    <th>
                        <a href="" ng-click="controller.predicate = 'plannedCollectionDate'; controller.reverse = !controller.reverse">Date</a>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr dir-paginate="collection in controller.results | orderBy: controller.predicate:controller.reverse | filter: controller.filter | itemsPerPage : controller.pageSize">
                    <td>
                        {{ collection.reference }}
                    </td>
                    <td>
                        {{ collection.customerReference }}
                    </td>
                    <td>
                        {{ collection.customerName }}
                    </td>
                    <td>
                        {{ collection.customerBusinessName }}
                    </td>
                    <td>
                        {{ collection.supplierName }}
                    </td>
                    <td>
                        {{ collection.collectionCode }}
                    </td>
                    <td>
                        {{ collection.status }}
                    </td>
                    <td>
                        {{ collection.plannedCollectionDate }}
                    </td>
                </tr>
            </tbody>
        </table>

        <dir-pagination-controls></dir-pagination-controls>

        <div class="form-group">
            <button class="btn btn-primary" ng-click="controller.save()">Import</button>
            <button class="btn btn-default" ng-click="controller.cancel()">Cancel</button>
        </div>
    </div>
</div>

当我单击“选择文件”并选择 CSV 文件时,上面的 HTML 会填充,我可以看到我的数据。 但问题是我想在显示它之前验证它,所以我试图通过函数将数据从指令传递到我的 Controller (因此是完整的函数),但是当我尝试 console.log 出数据时,我总是为空。

这是我的方法:

// Used to validate the imported data
self.validateResults = function (results) {

    console.log(self.results); // returns undefined
    console.log(results); // returns undefined
    console.log(self); // shows the results data as an array in self.results
};

HTML 中的指令如下所示:

 <input type="file" csv-reader results="controller.results" complete="controller.validateResults(results)" />

谁能向我解释一下我做错了什么?

最佳答案

当您使用结果调用回调时,您需要将其传递到带有键 results 的对象中:

if (scope.complete) {
    // Execute our callback
    scope.complete({results: scope.results});
}

传递给 scope.complete 的对象中的关键 results 对应于 HTML complete="controller.validateResults(results) 中定义的参数名称)”

关于javascript - AngularJS 指令回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30244842/

相关文章:

javascript - 传单.js : WMS Layer Styles

javascript - 如何在vue中加载目录的图像

javascript - babel.transform() 函数不使用 .babelrc 或 package.json 配置

javascript - JavaScript/循环混淆中的动态与词法范围界定

angularjs - 如果 Angular 应用程序加载失败/崩溃时显示消息?

javascript - 有条件地以 Angular 应用一次性绑定(bind)

javascript - 在nodejs和express中添加子域

javascript - 如何在不更改整个列表的情况下编辑列表中的项目?

javascript - 尝试在 stateChangeStart 中添加 token 时无法读取未定义的属性 'defaults'

javascript - AngularJS 更新表单并选择菜单选项?