2013-06-26 7 views
10

द्वारा लौटाया गया है मेरे पास AngularJS पर कुछ संसाधन हैं जो एक Tastypie API तक पहुंचते हैं। सब कुछ ठीक काम करता है, एक विस्तार के लिए छोड़कर:एंगुलरजेएस और जटिल JSON django tastypie

/api/v1/reminder/: tastypie हमेशा एक JSON, उदाहरण पर एक objects विशेषता के अंदर वास्तविक परिणाम संपुटित

{ 
    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() कॉल करने के लिए एक कॉलबैक का उपयोग कर ठीक करने के लिए wasy था :

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

अनुरोध डेटा के पढ़ने का विन्यास:

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

:

.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; 
    }); 
}]) 

अनुस्मारक लोड हो रहा है 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 

}); 
+1

आप कुछ [restangular] (https://github.com/mgonto/restangular) की कोशिश कर सकते हैं। – rtcherry

+0

व्हाओ, अच्छा लगता है .. मैं इसे देखूंगा –

+0

किया। यह एक कोणीय संसाधन के लिए एक विधि जोड़ने के रूप में आसान नहीं है, लेकिन किया जा सकता है .. लेकिन restangular इसकी कई उपयोगी सुविधाओं पर भुगतान करता है। क्या आप अपनी टिप्पणी का उत्तर देना चाहते हैं ताकि मैं इसे चिह्नित कर सकूं? –

उत्तर

6

आप एक अतिरिक्त लाइब्रेरी का उपयोग कर से बचना चाहते थे, तो आप निम्न कार्य करने में सक्षम होना चाहिए:

$resource('/api/v1/reminder/', {}, { 
    query: { 
     method: 'GET', 
     isArray: true, 
     transformResponse: $http.defaults.transformResponse.concat([ 
      function (data, headersGetter) { 
       return data.objects; 
      } 
     ]) 
    } 
}); 

यह आपके $HttpProvider के डिफ़ॉल्ट ट्रांसफार्मर को बदलने में संलग्न कर देगा।

नोट: अगर मैं इस पर गलत हूं तो मुझे सही करें लेकिन मेरा मानना ​​है कि इस सुविधा को v1.1.2 या इससे अधिक की आवश्यकता है।

+1

+1। – rtcherry

+0

मैं इसे आजमाने जा रहा हूं! मुझे पुनर्स्थापना के साथ कुछ परेशानी हो रही है जो मुझे एक पोस्ट अनुरोध पर प्रतिक्रिया नहीं दे रही है, और यह ngresource पर काम किया। बाद में वापस लौटने से मुझे कुछ समय बचाएगा। –

+1

कूल। आपके द्वारा लोड होने वाली पुस्तकालयों की संख्या को सीमित करना हमेशा अच्छा होता है। साथ ही, यहां एक उत्तर दिया गया है जिसे मैंने हाल ही में पोस्ट किया है, जिसने एक समान समस्या हल की है। http://stackoverflow.com/questions/17332922/how-can-i-insert-commands-before-or-prevent-https-jsonp-automatic-parsing-in-a/17333030#17333030 @ शमन एक रास्ता तलाश रहे थे डिफ़ॉल्ट परिवर्तन से पहले प्रतिक्रिया को बदलने के लिए। –

4

आप कर सकते हैं restangular जैसे कुछ कोशिश करना चाहते हैं।

उस कार्य को करने के लिए कुछ कॉन्फ़िगरेशन आवश्यक है। एक उदाहरण here है।

+0

मैं बाद में समाधान कोड के साथ अपना प्रश्न अपडेट करूंगा। AngularJS की 1.1.x शाखा से नई 'ngResource' सुविधाओं का उपयोग करने वाले समाधान को पोस्ट करने के लिए –

3

ऑब्जेक्ट को Reminder.query() (@moderndegree से उत्तर पर विस्तारित) के परिणामों पर सीधे meta ऑब्जेक्ट को संरक्षित करने के लिए मैंने निम्न कार्य करना समाप्त कर दिया।

var Reminder = $resource('/api/v1/reminder/', {}, { 
    query: { 
    method: 'GET', 
    isArray: true, 
    transformResponse: $http.defaults.transformResponse.concat([ 
     function (data, headersGetter) { 
      return data.objects; 
     } 
    ]), 
    interceptor: { 
     response: function(response) { 
     response.resource.meta = response.data.meta; 
     } 
    } 
    } 
}); 

आप लौटे वस्तु पर सीधे meta लाभ उठा सकें कि:

var reminders = Reminder.query(...); 
console.log(reminders.meta); // Returns `meta` as expected. 

मुझे लगता है कि यह भी Reminder.query के कॉलबैक के भीतर इसी प्रकार कुछ करने के लिए संभव हो जाएगा के बाद से response वस्तु उपलब्ध है वहाँ भी है।

संबंधित मुद्दे