2013-07-02 4 views
7

Der Ember.js REST-Adapter die JSON erwartet werden zurückgegeben, wie:Ember.js REST-Adapter ohne JSON root

{ 
    "person": { 
     "first_name": "Barack", 
     "last_name": "Obama", 
     "is_person_of_the_year": true 
    } 
} 

Aber meine API gibt die Daten ohne Wurzelelement:

{ 
    "first_name": "Barack", 
    "last_name": "Obama", 
    "is_person_of_the_year": true 
} 

Ist es möglich, den REST-Adapter so anzupassen, dass er meine JSON-Daten akzeptiert? Gerade jetzt ist es zeigt „Assertion failed: Ihr Server zurückgegeben einen Hash mit dem Schlüssel 0, aber Sie haben keine Zuordnung für sie

UPDATE: Basierend auf Sherwin Yus Antwort unten, das ist, was ich kam mit scheint so weit zu funktionieren: https://gist.github.com/richardkall/5910875

Antwort

8

Ja, Sie können Ihren eigenen benutzerdefinierten REST-Adapter schreiben. Sehen Sie sich den Quellcode in JSONSerializer, RESTSerializer (der den JSONSerializer erweitert) und REST adapter an.

Grundsätzlich müssen Sie die extract* Methoden aus dem JSONSerializer überschreiben.

Derzeit sieht es so etwas wie dieses:

extract: function(loader, json, type, record) { 
    var root = this.rootForType(type); 

    this.sideload(loader, type, json, root); 
    this.extractMeta(loader, type, json); 

    if (json[root]) { 
    if (record) { loader.updateId(record, json[root]); } 
    this.extractRecordRepresentation(loader, type, json[root]); 
    } 
}, 

Beachten Sie, wie es überprüft json[root] - Sie Ihre eigene Methode schreiben müsste auf der Grundlage Ihrer erwarteten API-Antwort.

Ein anderer Ansatz wäre es, die JSON von der API "vorverarbeiten", um ein Wurzelelement zu verwenden. Sie können dies tun, indem Sie herausfinden, welche Methoden extract* aufrufen (die es den JSON übergibt) und bevor es das tut, ändern Sie den JSON, um das Stammelement zu enthalten.

Hoffe, dass dies hilft, lass es mich wissen, wenn es unklar ist.

+0

Nizza Antwort. Vielen Dank! –

+0

Fantastisch! Vielen Dank! Dies scheint zu funktionieren: https://gist.github.com/richardkall/5910875 – Richard

-1

Ich habe versucht, Root zu Json hinzuzufügen. Das funktioniert für mich:

App.Adapter = DS.RESTAdapter.extend({ 
    findAll: function(store, type, since) { 
     var root, adapter; 
      var plural; // Insert this line 
     root = this.rootForType(type); 
     adapter = this; 
      plural = this.pluralize(root); // Insert this line 
     return this.ajax(
       this.buildURL(root), 
       "GET", 
       { 
        data: this.sinceQuery(since) 
       }).then(function(json) { 
        eval ("json = {" + plural + " : json }"); // Insert this line 
        adapter.didFindAll(store, type, json); 
       }).then(null, DS.rejectionHandler); 
    } 
}); 
+4

Manipulation der Antwort gehört in einen Serializer, kein Adapter. –

15

Sie könnten es auch in etwas normalisieren, das ember erwarten würde.

App.PersonSerializer = DS.RESTSerializer.extend({ 
    normalizePayload: function(type, payload) { 
    var typeKey = type.typeKey; 
    return { 
     typeKey: payload 
    } 
    } 
}); 
+1

'type' ist nicht mehr verfügbar, nur' Nutzlast'. http://emberjs.com/api/data/classes/DS.RESTSerializer.html # method_normalizePayload – rog

+0

Dies ist der Weg zu gehen, verglichen mit der akzeptierten Antwort, da der Entwickler sich keine Gedanken über den Typ der Nutzlast machen muss (Array, Einzelobjekt) und sich nicht um irgendwelche Speicheroperationen kümmern muss. – kiddouk

+0

Das ist die richtige Idee, aber der Code funktioniert nicht. Der Schlüssel des Rückgabewerts ist wörtlich "typeKey", nicht der Wert, der von 'var typeKey' gespeichert wird. – Andrew

1

Ich löste dies, indem ich DS.RESTSerializer erweiterte. Die extractArray-Methode muss überlastet werden, wenn die Serverantwort vom Typ Array ist.

App.PersonSerializer = DS.RESTSerializer.extend({ 
    extractSingle: function (store, type, payload, id) { 
     var wrappedObj = {}; 
     wrappedObj[type.typeKey] = payload; 
     return this._super(store, type, wrappedObj, id); 
    }});