我正在尝试构建一个AngularJS应用程序,它输出一个我用json填充的HTML表格(表格的HTML在这个问题的底部)。我正在使用从服务器检索的application/json
数据。
当我做一个简单的curl http://myurl.local/todo/api/v1/tasks
时,我得到了没有问题的json。如果我在这个块中放置一个console.log();
,我显然是从服务器获取json。
getJson: function() {
var url = 'http://myurl.local/todo/api/v1/tasks';
var promise = $http.get(url);
return promise.then(function(result) {
console.log("Got data ->" + result.data);
return result.data;
});
}
我正在使用Chrome开发应用;当我在Chrome中运行该应用时,Chrome的javascript控制台会在我到达TypeError: Cannot read property 'length' of undefined
行之前抛出此错误:console.log("Got data ->" + result.data);
。这是竞争条件。
错误非常清楚:
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
}, {
total: data.length, // length of data <--- Broken, needs a promise?
问题是javascript不是我的主要语言(它是Python);根据谷歌搜索我对这个问题所做的,我想我可以在正确的地方用一个承诺/ .then()
解决这个问题。但是我很难理解我应该如何在我的javascript中实现它。我想找到修复异步json GET的方法,并理解为什么需要这样做。
有人可以解释我应该如何解决这个问题,为什么我应该这样做呢?
JavaScript :
var App2 = angular.module('taskTable', ['ngRoute', 'ngTable']);
// Need to change AngularJS symbols when using flask + Jinja
App2.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
// Thank you PeteBD
// http://stackoverflow.com/a/12513509/667301
// Set up a controller to get json tasks...
App2.factory('getTasks', function($http) {
return {
getJson: function() {
var url = 'http://myurl.local/todo/api/v1/tasks';
var promise = $http.get(url);
return promise.then(function(result) {
return result.data;
});
}
}
});
App2.controller('tableCntl', function($scope, getTasks, $filter,
ngTableParams) {
var data = [];
getTasks.getJson().then(function(data) {
$scope.data = data;
});
data = $scope.data;
// Set up task table parameters
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
// store filtered data as $scope.tasks
var pageCount = params.page();
var paramCount = params.count();
$scope.tasks = orderedData.slice((pageCount-1)*paramCount,
pageCount*paramCount);
// set total for recalc pagination
params.total(orderedData.length);
$defer.resolve($scope.tasks);
}
});
});
// Props... angular.bootstrap() is required if two apps on the same page
// http://stackoverflow.com/a/18583329/667301
angular.bootstrap(document.getElementById("Tasks"),["taskTable"]);
HTML表格通过ngTable :
<div id="Tasks" ng-app="taskTable" ng-controller="tableCntl">
<p><strong>Filter:</strong> [[tableParams.filter()|json]]
<table ng-table="tableParams" show-filter="true" class="table">
<tbody>
<tr ng-repeat="task in $data">
<td data-title="'Description'" sortable="description"
filter="{'description': 'text'}">
[[task.description]]
</td>
<td data-title="'Priority'" sortable="priority"
filter="{'priority': 'text'}">
[[task.priority]]
</td>
<td data-title="'Entered'" sortable="entry">
[[task.entry]]
</td>
<td data-title="'Status'" sortable="status">
[[task.status]]
</td>
</tr>
</tbody>
</table>
</div>
答案 0 :(得分:3)
绝对值得一看ngResource - 这将为您解决所有繁重的工作。
另一方面,我怀疑你不需要这样做:
App2.factory('getTasks', function($http) {
return {
getJson: function() {
var url = 'http://myurl.local/todo/api/v1/tasks';
var promise = $http.get(url);
return promise.then(function(result) {
return result.data;
});
}
}
});
我会将其更改为:
App2.factory('getTasks', function($http) {
return {
getJson: function() {
var url = 'http://myurl.local/todo/api/v1/tasks';
return $http.get(url);
}
}
});
$ http返回承诺。这意味着这一点仍然有效:
getTasks.getJson().then(function(data) {
$scope.data = data;
});