2013-06-25 89 views
8

我有一个基于AngularJS的前端使用restangular从我构建的Django后端获取记录。AngularJS/Restangular路由“不能设置属性'路由'未定义”

我正在做一个客户端列表中的电话有以下:

var app; 

app = angular.module("myApp", ["restangular"]).config(function(RestangularProvider) { 
    RestangularProvider.setBaseUrl("http://172.16.91.149:8000/client/v1"); 
    RestangularProvider.setResponseExtractor(function(response, operation) { 
    return response.objects; 
    }); 
    return RestangularProvider.setRequestSuffix("/?callback=abc123"); 
}); 

angular.module("myApp").controller("MainCtrl", function($scope, Restangular) { 
    return $scope.client = Restangular.all("client").getList(); 
}); 

Chrome正在显示后端与HTTP 200返回数据:

abc123({ 
    "meta": { 
     "limit": 20, 
     "next": "/client/v1/client/?callback=abc123&limit=20&offset=20", 
     "offset": 0, 
     "previous": null, 
     "total_count": 2 
    }, 
    "objects": [{ 
     "id": 1, 
     "name": "Test", 
     "resource_uri": "/client/v1/client/1/" 
    }, { 
     "id": 2, 
     "name": "Test 2", 
     "resource_uri": "/client/v1/client/2/" 
    }] 
}) 

但一旦出现这种情况我m看到Chrome控制台中出现以下堆栈跟踪:

TypeError: Cannot set property 'route' of undefined 
    at restangularizeBase (http://172.16.91.149:9000/components/restangular/src/restangular.js:395:56) 
    at restangularizeCollection (http://172.16.91.149:9000/components/restangular/src/restangular.js:499:35) 
    at http://172.16.91.149:9000/components/restangular/src/restangular.js:556:44 
    at wrappedCallback (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6846:59) 
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6883:26 
    at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8057:28) 
    at Object.Scope.$digest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:7922:25) 
    at Object.Scope.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8143:24) 
    at done (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9170:20) 
    at completeRequest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9333:7) angular.js:5754 

我做了一个断点就在restangular.js行395:

L394 function restangularizeBase(parent, elem, route) { 
L395  elem[config.restangularFields.route] = route; 

它击中断点elem第一次只是一个对象,routeclient值。

第二次遇到断点elem未定义,route的值为client

任何想法为什么elem将第二次未定义?

回答

8

我是Restangular的创造者。

首先为您的集合调用restangularizeBase函数,然后为每个元素调用restangularizeBase函数。

从StackTrace中,元素是可以的,但一旦收集发送到restangularizeBase,它实际上是未定义的。你可以请console.log response.objects?另外,请更新至最新版本。

另外,对于默认的请求参数,您应该使用defaultRequestParams而不是requestSuffix。 requestSuffix只能用于结尾“/”

让我知道如果我可以帮助你更多!

19

当请求列表时,Restangular期望来自服务器的数据是一个简单的数组。但是,如果生成的数据包含结果元数据(如分页信息),则会崩溃。

如果您正在使用Django的REST框架,它会返回结果裹这样的:

{ 
    "count": 2, 
    "next": null, 
    "previous": null, 
    "results": [ 
     { 
      "id": 1, 
      "name": "Foo" 
     }, 
     { 
      "id": 2, 
      "name": "Bar" 
     } 
    ] 
} 

要翻译这一点,你需要创建一个响应提取功能。最简单的方法在模块配置来指定:

angular.module('myApp', ['myApp.controllers', 'restangular']). 
config(function(RestangularProvider) { 
    RestangularProvider.setBaseUrl("/api"); 

    // This function is used to map the JSON data to something Restangular 
    // expects 
    RestangularProvider.setResponseExtractor(function(response, operation, what, url) { 
     if (operation === "getList") { 
      // Use results as the return type, and save the result metadata 
      // in _resultmeta 
      var newResponse = response.results; 
      newResponse._resultmeta = { 
       "count": response.count, 
       "next": response.next, 
       "previous": response.previous 
      }; 
      return newResponse; 
     } 

     return response; 
    }); 
}); 

此重新排列的结果是一个简单的阵列,与_resultmeta的一个附加属性,包含元数据。 Restangular会对数组进行处理,它是对象,并且可以像处理期望的那样在处理数组时处理_resultmeta属性。

+2

@ mark-l我建议你把这个标记为答案。谢谢。 –