AngularJS / Promises / DataTables - Table 中没有数据
AngularJS / Promises / DataTables - No Data in Table
我在提供的模块中有一个控制器,它使用来自 JSON 文件或 API 调用的数据。 JSON 文件版本 GetActionItems2()
完美运行。不幸的是,我无法让 GetActionItems()
像它的对应函数(JSON 版本)那样工作。我正在使用延期承诺和 Angular 数据表。控制台没有错误,但我的 table 在页面中没有数据。
我该如何解决这个问题?
控制器
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
$http.get('api/actionitems')
.then(function(response){
defer.resolve(response);
});
return defer.promise;
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result) {
$scope.actionitems = result;
defer.resolve(result);
});
return defer.promise;
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
模板
<div ng-init="init()" ng-controller="ActionController">
ActionItems
<table id="actionitems" class="row-border hover action" datatable="" dt-options="dtOptions">
<thead>
<tr>
<th>
ID
</th>
<th>
Action Item Title
</th>
<th>
Criticality
</th>
<th>
Assignor
</th>
<th>
Owner
</th>
<th>
Alt Owner
</th>
<th>
Approver
</th>
<th>
Assigned Date
</th>
<th>
DueDate
</th>
<th>
ECD
</th>
<th>
Completion Date
</th>
<th>
Closed Date
</th>
<th>
Team
</th>
<th>
Meeting
</th>
<th>
Phase
</th>
<th>
Source
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="actionitem in actionitems">
<td>{{actionitem.ActionItemID}}</td>
<td>{{actionitem.Title}}</td>
<td>{{actionitem.Criticality}}</td>
<td>{{actionitem.Assignor}}</td>
<td>{{actionitem.Owner}}</td>
<td>{{actionitem.AltOwner}}</td>
<td>{{actionitem.Approver}}</td>
<td>{{actionitem.AssignedDate}}</td>
<td>{{actionitem.DueDate}}</td>
<td>{{actionitem.ECD}}</td>
<td>{{actionitem.CompletionDate}}</td>
<td>{{actionitem.ClosedDate}}</td>
</tbody>
</table>
</div>
如果此异步处理来自第三方,您可能需要手动触发该控制器的数据更新。
// ...
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result) {
$scope.actionitems = result;
// here trigger a data update
$scope.$digest();
defer.resolve(result);
});
return defer.promise;
})
// ...
The $digest
method is to manually trigger the change detection of the controller.
查看下面的编辑
我最初的解决方案是分两步将数据导入我的 table。
我引入了一个自定义 apply
函数,然后引入了一个 getRes
函数,该函数随后使用单个操作项填充了操作项数组,其中只有一组值被发送到数据 tables并分配给 $scope.acionitems
。否则我会从 datatables 得到一个警告,关于每个项目的格式是 JSON 格式和相应的键。
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
$http.get('api/actionitems')
.then(function(response){
defer.resolve(response);
});
return defer.promise;
}
var getRes = function(res){
$.each(res, function(key, actionitem){
res[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = res;
}
function apply(scope, fn, res) {
(scope.$$phase || scope.$root.$$phase) ?
fn(res) :
scope.$apply(fn(res));
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result){
apply($scope, getRes, result.data);
defer.resolve(result.data);
});
return defer.promise;
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
编辑
我简化了代码并对结果的实际数据属性使用了解析,而不是在我的 table.
中生成数据的对象本身
以下基于我的反模式用法的修改是迄今为止我能达到的相同结果的最佳修改。
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
var res = $http.get('api/actionitems').then(function(result){
var data = result.data;
$.each(data, function(key, actionitem){
data[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = data;
defer.resolve(data);
});
return defer.promise;
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder
.fromFnPromise(GetActionItems)
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
将 $http.get('api/actionitems').then(function(result)
返回到 fromFnPromise
并在 function(result)
内嵌入 return result.data
解决了该问题并避免了延迟反模式的使用。
$scope.init = function() {
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
return $http.get('api/actionitems').then(function(result) {
$.each(result.data, function(key, actionitem) {
result.data[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = result.data;
return result.data;
});
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
我在提供的模块中有一个控制器,它使用来自 JSON 文件或 API 调用的数据。 JSON 文件版本 GetActionItems2()
完美运行。不幸的是,我无法让 GetActionItems()
像它的对应函数(JSON 版本)那样工作。我正在使用延期承诺和 Angular 数据表。控制台没有错误,但我的 table 在页面中没有数据。
我该如何解决这个问题?
控制器
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
$http.get('api/actionitems')
.then(function(response){
defer.resolve(response);
});
return defer.promise;
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result) {
$scope.actionitems = result;
defer.resolve(result);
});
return defer.promise;
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
模板
<div ng-init="init()" ng-controller="ActionController">
ActionItems
<table id="actionitems" class="row-border hover action" datatable="" dt-options="dtOptions">
<thead>
<tr>
<th>
ID
</th>
<th>
Action Item Title
</th>
<th>
Criticality
</th>
<th>
Assignor
</th>
<th>
Owner
</th>
<th>
Alt Owner
</th>
<th>
Approver
</th>
<th>
Assigned Date
</th>
<th>
DueDate
</th>
<th>
ECD
</th>
<th>
Completion Date
</th>
<th>
Closed Date
</th>
<th>
Team
</th>
<th>
Meeting
</th>
<th>
Phase
</th>
<th>
Source
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="actionitem in actionitems">
<td>{{actionitem.ActionItemID}}</td>
<td>{{actionitem.Title}}</td>
<td>{{actionitem.Criticality}}</td>
<td>{{actionitem.Assignor}}</td>
<td>{{actionitem.Owner}}</td>
<td>{{actionitem.AltOwner}}</td>
<td>{{actionitem.Approver}}</td>
<td>{{actionitem.AssignedDate}}</td>
<td>{{actionitem.DueDate}}</td>
<td>{{actionitem.ECD}}</td>
<td>{{actionitem.CompletionDate}}</td>
<td>{{actionitem.ClosedDate}}</td>
</tbody>
</table>
</div>
如果此异步处理来自第三方,您可能需要手动触发该控制器的数据更新。
// ...
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result) {
$scope.actionitems = result;
// here trigger a data update
$scope.$digest();
defer.resolve(result);
});
return defer.promise;
})
// ...
The
$digest
method is to manually trigger the change detection of the controller.
查看下面的编辑
我最初的解决方案是分两步将数据导入我的 table。
我引入了一个自定义 apply
函数,然后引入了一个 getRes
函数,该函数随后使用单个操作项填充了操作项数组,其中只有一组值被发送到数据 tables并分配给 $scope.acionitems
。否则我会从 datatables 得到一个警告,关于每个项目的格式是 JSON 格式和相应的键。
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
$http.get('api/actionitems')
.then(function(response){
defer.resolve(response);
});
return defer.promise;
}
var getRes = function(res){
$.each(res, function(key, actionitem){
res[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = res;
}
function apply(scope, fn, res) {
(scope.$$phase || scope.$root.$$phase) ?
fn(res) :
scope.$apply(fn(res));
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
GetActionItems().then(function(result){
apply($scope, getRes, result.data);
defer.resolve(result.data);
});
return defer.promise;
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
编辑
我简化了代码并对结果的实际数据属性使用了解析,而不是在我的 table.
中生成数据的对象本身以下基于我的反模式用法的修改是迄今为止我能达到的相同结果的最佳修改。
angular.module('Action').controller('ActionController', ['$http', '$resource', '$scope', '$state', '$timeout', '$q', 'DTOptionsBuilder', function($http, $resource, $scope, $state, $timeout, $q, DTOptionsBuilder){
$scope.actionitems = {};
function GetActionItems2()
{
return $resource('actionitems.json').query().$promise;
}
function GetActionItems() {
var defer = $q.defer();
var res = $http.get('api/actionitems').then(function(result){
var data = result.data;
$.each(data, function(key, actionitem){
data[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = data;
defer.resolve(data);
});
return defer.promise;
}
$scope.init = function(){
var vm = this;
vm.dtOptions = DTOptionsBuilder
.fromFnPromise(GetActionItems)
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}
}]);
将 $http.get('api/actionitems').then(function(result)
返回到 fromFnPromise
并在 function(result)
内嵌入 return result.data
解决了该问题并避免了延迟反模式的使用。
$scope.init = function() {
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
return $http.get('api/actionitems').then(function(result) {
$.each(result.data, function(key, actionitem) {
result.data[key] = [
actionitem.actionitemid,
actionitem.actionitemtitle,
actionitem.criticality,
actionitem.assignor,
actionitem.owner,
actionitem.altowner,
actionitem.approver,
actionitem.assigneddate,
actionitem.duedate,
actionitem.ecd,
actionitem.completiondate,
actionitem.closeddate
];
});
$scope.actionitems = result.data;
return result.data;
});
})
.withPaginationType('full_numbers')
//.withOption('drawCallback', reload)
.withDisplayLength(10)
//.withOption('order', [1, 'desc'])
.withOption('scrollY', 500)
.withOption('scrollX', '100%')
.withDOM('lftrpi')
.withScroller();
}