AngularJS指令回调函数

时间:2015-05-14 18:38:58

标签: 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会填充,我可以看到我的数据。 但问题是我想在显示它之前验证它,所以我试图通过一个函数(因此完整的函数)将数据从指令传递给我的控制器,但是当我尝试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)" />

任何人都可以向我解释我做错了吗?

1 个答案:

答案 0 :(得分:1)

当您使用结果调用回调时,需要使用键results将其传递给对象:

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

您传递给results的对象中的密钥scope.complete对应于HTML complete="controller.validateResults(results)"中定义的参数名称。