2014-03-12 94 views
1

我想构建一个AngularJS应用程序,它输出一个我用json填充的HTML表格(表格的HTML是在这个问题的底部)。我正在使用从我的服务器检索到的application/json数据。与json数据异步填充AngularJS ngTable

当我做一个简单的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是不是我的主要语言(这是蟒蛇);基于我对这个问题所做的搜索引擎优化,我认为我可以在正确的地方修复这个问题/ .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

喜,这是正确的语法:[task.description],你应该使用{{task.description}}仪式,如果可能的话,在jsfiddle.net –

+0

发布此Hi @MikePennington您在这里展示的代码以及所有解决方案的效果如何?我得到的数据为Undefined,但是如果我在getTasks.getJson()中记录数据,那么()我得到所有我期望的数据。有没有另一种与这种方法有关的关于异步使用JSON数据填充AngularJS ngTable的代码?提前致谢。 –

回答

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; 
    }); 
+1

终于找到了问题的其余部分......我不得不将'$ defer.resolve($ scope.tasks);'改为'$ defer.resolve(data);'。 ngResource确实简化了代码。 –

+0

酷!很高兴你把事情解决了! –