10

Tastypie API にアクセスする AngularJS で書かれたリソースはほとんどありません。詳細を除いて、すべて正常に動作します。tastypie は常にobjectsJSON の属性内に実際の結果をカプセル化します。例:

/api/v1/reminder/:

{
    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",
        id: 1,
        repeat: "weekly",
        resource_uri: "/api/v1/reminder/1",
        value: "-50"
    }, {
        category: {
            color: "#999999",
            id: 1,
            name: "Groceries",
            resource_uri: "/api/v1/category/1"
        },
        description: "",
        due_date: "2010-10-17",
        id: 2,
        repeat: "weekly",
        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;
}])

次に、クラスに動作を実装する必要があります。また、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 に、すべてのオブジェクトobjectsが実際の結果であることを理解させて、インスタンスのリストのように振る舞わせますか?

回避策は、インスタンスを作成する結果を反復する新しいリストを作成することですが、最適ではありません...

提案?

@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();
}

私のカスタムメソッドをReminder(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', ['$resource', '$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

});
4

3 に答える 3

4

restangularのようなものを試してみてください。

それを機能させるには、いくつかの構成が必要です。例はこちらです。

于 2013-06-26T09:48:20.930 に答える