AngularJS和复杂JSON由django tastypie返回

前端之家收集整理的这篇文章主要介绍了AngularJS和复杂JSON由django tastypie返回前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在AngularJS上写了几篇关于访问Tastypie API的资源.一切工作正常,除了一个细节:tastypie总是将实际结果封装在 JSON的对象属性中,例如:

/ API / V1 /提醒/:

{
    Meta: {
        limit: 20,next: null,offset: 0,prevIoUs: null,total_count: 3
    },objects: [{
        category: {
            color: "#999999",id: 1,name: "Groceries",resource_uri: "/api/v1/category/1"
        },description: "",due_date: "2010-10-16",repeat: "weekly",resource_uri: "/api/v1/reminder/1",value: "-50"
    },{
        category: {
            color: "#999999",due_date: "2010-10-17",id: 2,resource_uri: "/api/v1/reminder/2",value: "-50"
    }
}

使用回调到get()调用是很痛苦的:

Reminder.get().$then(function (result) {
    $scope.reminders  = result.data.objects;
});

但是我知道result.resource是一个实际的Reminder实例.

.factory('Reminder',['$resource',function($resource){
    var Reminder = $resource('/api/v1/reminder/:id',{},{
        get: {
            method: 'GET',isArray: false
        }
    });

    Reminder.prototype.TESTE = function () {console.log('asd');};

    return Reminder;
}])

现在我需要在我的提醒类上实现行为,我需要我的Meta.objects上的每一个元素都是一个Reminder的实例:

Reminder.get().$then(function (result) {
    $scope.reminders  = result.data.objects;

    result.resource.TESTE(); // -> outputs 'asd'

    o = result.data.objects[0];
    o.TESTE // -> undefined,obvisously
    i = new Reminder(o);
    i.TESTE() // -> outputs 'asd'
});

那么,我如何得到angularjs来了解对象上的每个对象是实际的结果,所以它的行为就像一个实例列表?

解决办法是创建一个新的列表,迭代创建实例的结果,但它不是最佳的…

建议?

@rtcherry解决方案:

根据rtcherry的建议,我用了restangular

配置读取请求数据:

.config(['RestangularProvider',function(RestangularProvider) {
    RestangularProvider.setBaseUrl("/api/v1");

    RestangularProvider.setResponseExtractor(function(response,operation,what,url) {
        var newResponse;
        if (operation === "getList") {
            newResponse = response.objects;
            newResponse.Metadata = response.Meta;
        } else {
            newResponse = response.data;
        }
        return newResponse;
    });
}])

载入提醒:

function RemindersCtrl ($scope,$rootScope,Reminder) {
    $scope.reminders = Reminder.getList();
}

将我的自定义方法添加到提醒(不如ngResource那么干净但可行):

.factory('Reminder',['Restangular','$filter',function(Restangular,$filter){
    var Reminder = Restangular.all('reminder');

    var remainingDays = function () {
        //do stuff
    };

    // adding custom behavior
    Restangular.addElementTransformer('reminder',false,function (reminder) {
        reminder.remainingDays = remainingDays;
        return reminder;
    });

    return Reminder;
}])

@moderndegree的解决方

我使用纯ngResource:

var tastypieDataTransformer = function ($http) {
    return $http.defaults.transformResponse.concat([
        function (data,headersGetter) {
            var result = data.objects;
            result.Meta = data.Meta;
            return result;
        }
    ])
};

...

.factory('Reminder','$http',function($resource,$http){
    var Reminder = $resource('/api/v1/reminder/:id',{
        query: {
            method: 'GET',isArray: true,transformResponse: tastypieDataTransformer($http)
        }
    });

    Reminder.prototype.remainingDays = function () {
        // doing stuff
    };

    return Reminder;
}])

我的控制器:

Transaction.query(filter).$then(function (result) {
    $scope.days = [];
    var transactions = result.resource;
    resource[0].remainingDays(); // it works

});
如果您想避免使用其他库,您应该可以执行以下操作:
$resource('/api/v1/reminder/',{
    query: {
        method: 'GET',transformResponse: $http.defaults.transformResponse.concat([
            function (data,headersGetter) {
                return data.objects;
            }
        ])
    }
});

这将附加您的转换为$HttpProvider的默认变压器.

注意:如果我错了,我相信这个功能需要v1.1.2或更高版本.

猜你在找的Angularjs相关文章