Javascript 根据承诺的结果向动态ng表添加列
我最近一直在使用Javascript 根据承诺的结果向动态ng表添加列,javascript,angularjs,ngtable,Javascript,Angularjs,Ngtable,我最近一直在使用ngTableDynamic指令,当我确切地知道我的表应该期望哪些列时,它非常有效。然而,当我的表是真正动态的,并且我事先不知道所期望的列的数量或类型时,我会遇到一些问题 在控制器顶部,我声明我知道的列将出现在每个表中: $scope.columns = [ { title: 'ID', field: 'id', visible: true, required: true }, { title: 'Email', field: 'email', visible: true
ngTableDynamic
指令,当我确切地知道我的表应该期望哪些列时,它非常有效。然而,当我的表是真正动态的,并且我事先不知道所期望的列的数量或类型时,我会遇到一些问题
在控制器顶部,我声明我知道的列将出现在每个表中:
$scope.columns = [
{ title: 'ID', field: 'id', visible: true, required: true },
{ title: 'Email', field: 'email', visible: true, required: true }
];
然后,我对返回结果的服务进行异步调用。基于这些结果,我将任何其他列对象推入$scope.columns
:
var getResults = function() {
var defer = $q.defer();
reportService.getReportResults({
report: $scope.id,
version: $scope.version
}).$promise.then(function(data) {
$scope.data = data.results;
_.each($scope.data[0], function(value, key) {
if (key !== 'id' && key !== 'email') {
$scope.columns.push({
title: _str.capitalize(key),
field: key,
visible: true,
required: false
});
}
});
defer.resolve($scope.data);
});
return defer.promise;
};
但是,在中推送的列。当我在浏览器中查看时,每个都不会出现在我的表中。但是,如果我将异步调用替换为示例数据集的硬编码模拟,则会添加列,并且一切都会按预期工作:
var getResults = function() {
var defer = $q.defer();
$scope.data = [{"id":"1","email":"test@sample.com",,"create_date":"2013-09-03T09:00:00.000Z"},{"id":"2","email":"sample@test.org","create_date":"2013-09-03T11:10:00.000Z"}];
_.each($scope.data[0], function(value, key) {
if (key !== 'id' && key !== 'email') {
$scope.columns.push({
title: _str.capitalize(key),
field: key,
visible: true,
required: false
});
}
});
defer.resolve($scope.data);
return defer.promise;
};
在我的控制器下面,我的初始化代码调用
getResults().then(function() {
$scope.tableParams.reload();
});
$scope.tableParams = new ngTableParams({...
我的假设是,一旦承诺得到解决,$scope.tableParams.reload()在$scope.列更新之前调用code>。基于文档,用承诺来做例子是非常必要的。
在从promise得到响应之后,似乎必须创建新的tableParams和cols对象。向现有COL添加行可能不会触发watcher
angular.module('app',['ngTable']);
角度.module('app').controller('Demo',函数($scope,NgTableParams,dataService){
$scope.cols=[{
标题:“ID”,
字段:“id”,
可见:正确
}, {
标题:“电子邮件”,
字段:“电子邮件”,
可见:正确
}, {
标题:“创建日期”,
字段:“创建_日期”,
可见:正确
}];
数据服务
.getData()
.然后(功能(响应){
$scope.tableParams=新的NgTableParams({}{
数据集:response.results
});
$scope.cols=$scope.cols.concat(response.cols);
});
});
角度.module('app').factory('dataService',函数($timeout){
返回{
getData:function(){
返回$timeout(函数(){
var n=Math.round(Math.random()*50)+5;
var结果=[];
对于(变量i=0;i
{{row[col.field]}
原因是您将数据异步应用于$scope(在promise-then块中),因此您处于角度摘要周期之外,并且您的表不会更新
这不会发生在模拟中,因为您同步设置了$scope.data。
()
要解决此问题,您应该通知angular您已使用$scope对作用域进行了一些更改。$digest()
我发现您的代码还存在一些其他问题,我将尝试解决这些问题
- 承诺的错误用法(阅读:尽可能避免“延迟”)
- 无功能方法
- 一般来说,对承诺/角度有点困惑
说得够多了,我要这样写你的函数:
var getResults = function() {
// fetch data
return reportService.getReportResults( {
report: $scope.id,
version: $scope.version
} )
.then( function( data ) {
// assign the values
$scope.data = data.results
// notify angular to recheck his array
$scope.$digest()
// consider using a functional approach to have a cleaner code
_( $scope.data )
.first()
.keys()
.filter( key => ( key !== 'id' && key !== 'email' ) )
.each( key => {
$scope.columns.push( {
title: _str.capitalize( key ),
field: key,
visible: true,
required: false
} )
} )
.value()
return $scope.data
} )
}
试一试
var getResults = function() {
var defer = $q.defer();
reportService.getReportResults({
report: $scope.id,
version: $scope.version
}).$promise.then(defer.resolve);
return defer.promise;
};
getResults().then(function(_data) {
$scope.data = _data;
_.each($scope.data, function(value, key) {
if (key !== 'id' && key !== 'email') {
$scope.columns.push({
title: _str.capitalize(key),
field: key,
visible: true,
required: false
});
}
});
});
或直接在控制器中作为
reportService.getReportResults({
report: $scope.id,
version: $scope.version
}).then(function(_data) {
$scope.data = _data;
_.each($scope.data, function(value, key) {
if (key !== 'id' && key !== 'email') {
$scope.columns.push({
title: _str.capitalize(key),
field: key,
visible: true,
required: false
});
}
});
});
如果移动该getResults(),硬编码的模拟版本会发生什么情况?(…
在实例化$scope.tableParams
后调用?嗨,我对Angular不是很精通,但是你能告诉我$promise
在这里的意思吗?版本:$scope.version}).$PROMITE
我以前从未见过这样的事情。@Mridul,找到$promise@AsimKT我知道承诺。我是说,我从来没有见过这样的用法。通过链接$promise
。您能给我举个例子吗?@Mridul您可能没有看到,因为我们大多数时候都使用$http进行API调用$promise带有$resource,它提供原始promise对象。阅读我分享的关于$PROMITE的部分。示例也在文档中。