所以我有一个指令接受一个回调函数作为一个参数与其他一些选项。 这是指令:
.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)" />
任何人都可以向我解释我做错了吗?
答案 0 :(得分:1)
当您使用结果调用回调时,需要使用键results
将其传递给对象:
if (scope.complete) {
// Execute our callback
scope.complete({results: scope.results});
}
您传递给results
的对象中的密钥scope.complete
对应于HTML complete="controller.validateResults(results)"
中定义的参数名称。