我想建立一个AngularJS应用程序,用于输出我使用JSON填充一个HTML表(该表的HTML是这个问题的底部)。我使用,我从我的服务器中检索应用程序/ JSON
数据。
当我做一个简单的卷曲的http://myurl.local/todo/api/v1/tasks
,我得到的,没有任何问题JSON。如果我把一个的console.log();
此块中,我清楚地从服务器获取的JSON
的getJSON:功能(){ VAR URL =HTTP://myurl.local/todo/api/v1/tasks'; VAR承诺= $ http.get(URL); 返回promise.then(功能(结果){ 的console.log(拿到数据 - >中+ result.data); 返回result.data; }); }
我使用Chrome浏览器开发的应用程序;当我运行在Chrome应用程序,Chrome的JavaScript控制台抛出这个错误:类型错误:无法读取的未定义的属性长度
之前,我到控制台.LOG(得到的数据 - >中+ result.data);
行。这是一个竞争条件。
该错误是很清楚在这里:
$ scope.tableParams =新ngTableParams({ 页面:1,//显示第一页 数:10,//每页计 },{ 总:数据&LT的data.length,//长度---破,需要一个承诺?
问题是,JavaScript是不是我的主要语言(这是蟒蛇);基础上的谷歌搜索,我对这个问题做了,我想我可以用在正确的地方的承诺/ 。然后()
解决这个问题。不过我有困难的确切理解我应该怎么在我的JavaScript实现这一点。我想找到解决异步JSON GET的方式,并明白为什么需要做这样的。
有人能解释一下我应该怎么解决这个问题,我为什么要那样做?
的中的JavaScript 的:
VAR App2的= angular.module('taskTable',['ngRoute','ngTable']); //需要使用瓶+神社时改变AngularJS符号 App2.config(函数($ interpolateProvider){ $ interpolateProvider.startSymbol('[['); $ interpolateProvider.endSymbol(']'); }); //谢谢PeteBD // http://stackoverflow.com/a/12513509/667301 //设置一个控制器来获得JSON的任务... App2.factory('getTasks',函数($ HTTP){ 返回{ 的getJSON:功能(){ VAR URL =HTTP://myurl.local/todo/api/v1/tasks'; VAR承诺= $ http.get(URL); 返回promise.then(功能(结果){ 返回result.data; }); } } }); App2.controller('tableCntl',函数($范围,getTasks,$过滤器, ngTableParams){ VAR数据= []; getTasks.getJson()。然后(功能(数据){ $ scope.data =数据; }); 数据= $ scope.data; //设置任务表参数 $ scope.tableParams =新ngTableParams({ 页面:1,//显示第一页 数:10,//每页计 },{ 总:data.length,//数据的长度 的getData:函数($延迟,则params){ //使用内置的角度过滤器 VAR orderedData = params.filter()? $过滤器('过滤器')(数据,params.filter()): 数据; //存储过滤后的数据为$ scope.tasks VAR = PAGECOUNT params.page(); 变种paramCount = params.count(); $ scope.tasks = orderedData.slice((PAGECOUNT-1)* paramCount, * PAGECOUNT paramCount); //设置为总重计算分页 params.total(orderedData.length); $ defer.resolve($ scope.tasks); } }); }); //道具... angular.bootstrap()需要在同一页上,如果两个应用程序 // http://stackoverflow.com/a/18583329/667301 angular.bootstrap(的document.getElementById(任务),[taskTable]);
的 ngTable 的HTML表格:
< DIV ID =任务NG-应用=taskTableNG控制器=tableCntl> < P><强大的过滤器过滤:LT; / STRONG> [tableParams.filter()| JSON] <表NG表=tableParams显示过滤器=真正的类=表> <&TBODY GT; < TR NG重复=任务$数据> < TD数据标题=说明排序=说明 过滤器={说明:文本}> [[任务描述]] < / TD> < TD数据标题='优先级'排序=优先权 过滤器={'优先':'文字'}> [task.priority] < / TD> < TD数据标题=输入排序=项> [task.entry] < / TD> < TD数据标题=状态排序=状态> [task.status] < / TD> < / TR> < / TBODY> < /表> < / DIV>
解决方案
绝对值得看的 ngResource - 这将只是采取了所有的繁重你
在另一方面,我怀疑你并不需要这样做:
App2.factory('getTasks',函数($ HTTP){ 返回{ 的getJSON:功能(){ VAR URL =HTTP://myurl.local/todo/api/v1/tasks'; VAR承诺= $ http.get(URL); 返回promise.then(功能(结果){ 返回result.data; }); } }});
我将其更改为:
App2.factory('getTasks',函数($ HTTP){ 返回{ 的getJSON:功能(){ VAR URL =HTTP://myurl.local/todo/api/v1/tasks'; 返回$ http.get(URL); } }});
由于$ HTTP返回的承诺。这意味着,此位仍然有效:
getTasks.getJson()。然后(功能(数据){ $ scope.data =数据; });
I'm trying to build an AngularJS app, which outputs an HTML table that I populate with json (the table's HTML is at the bottom of this question). I'm using application/json
data that I retrieve from my server.
When I do a simple curl http://myurl.local/todo/api/v1/tasks
, I get json with no problems. If I put a console.log();
inside this block, I'm clearly getting the json from the server.
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;
});
}
I'm using Chrome to develop the app; when I run the app in Chrome, Chrome's javascript console throws this error: TypeError: Cannot read property 'length' of undefined
before I get to that console.log("Got data ->" + result.data);
line. It's a race condition.
The error is very clearly right here:
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
}, {
total: data.length, // length of data <--- Broken, needs a promise?
The problem is that javascript isn't my primary language (it's Python); based on the googling I've done about this problem, I think I could fix this with a promise / .then()
in the right place. However I'm having difficulty understanding exactly how I should implement this in my javascript. I would like to find the way to fix the async json GET, and understand why it needs to be done that way.
Could someone explain how I should fix this, and why I should do it that way?
The 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"]);
The HTML table via 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>
解决方案
Definitely worth looking at ngResource - this will simply take out all the heavy lifting for you.
On another note, I suspect you don't need to do this:
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;
});
}
}
});
i would change it to :
App2.factory('getTasks', function($http) {
return {
getJson: function() {
var url = 'http://myurl.local/todo/api/v1/tasks';
return $http.get(url);
}
}
});
As $http returns the promise. That means this bit still works:
getTasks.getJson().then(function(data) {
$scope.data = data;
});