2013-10-26 17 views
62

Ich benutze Ember.js mit lokalen-Speicher-Adapter. Ich habe ein seltsames Problem beim Aktualisieren von Datensätzen.Ember js - Hasmany Beziehungen bricht nach der Aktualisierung anderer Tabellen

Ich habe einen Post und Kommentare Modell mit hasMany Beziehungen:

App.Post = DS.Model.extend({ 
    title: DS.attr('string'), 
    comments: DS.hasMany('comment', { 
     async: true 
    }) 
}); 
App.Comment = DS.Model.extend({ 
    message: DS.attr('string') 
}); 

Diese meine Post und Kommentare sind Controller:

App.PostsController = Ember.ArrayController.extend({ 
    newTitle: '', 
    actions: { 
     create: function() { 
      var title = this.get('newTitle'); 
      var post = this.store.createRecord('post', { 
       title: title 
      }); 
      this.set('newTitle', ''); 
      post.save(); 
     } 
    } 
}); 
App.CommentsController = Ember.ArrayController.extend({ 
    needs: "post", 
    post: Ember.computed.alias("controllers.post.model"), 
    newMessage: '', 
    actions: { 
     create: function() { 
      var message = this.get('newMessage'); 
      var comment = this.store.createRecord('comment', { 
       message: message 
      }); 
      var post = this.get('post'); 
      var comments = post.get('comments'); 
      if (comments.get('content') == null) comments.set('content', []); 
      comments.pushObject(comment); 
      comment.save(); 
      post.save(); 
     } 
    } 
}); 

Beim Erstellen Aufzeichnungen hasMany Beziehungen korrekt aktualisiert.

{ 
    "App.Post": { 
     "records": { 
      "0v66j": { 
       "id": "0v66j", 
       "title": "post1", 
       "comments": ["p31al", "tgjtj"] 
      } 
     } 
    }, 
    "App.Comment": { 
     "records": { 
      "p31al": { 
       "id": "p31al", 
       "message": "comment 1" 
      }, 
      "tgjtj": { 
       "id": "tgjtj", 
       "message": "comment 2" 
      } 
     } 
    } 
} 

Das Problem trat beim Bearbeiten von Post auf. Die Beziehungen sind nach dem Bearbeiten des Postdatensatzes verschwunden. Ich habe etwas gesucht und diesen Code gefunden:

DS.JSONSerializer.reopen({ 
    serializeHasMany: function(record, json, relationship) { 
     var key = relationship.key; 
     var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship); 
     // alert(relationshipType); 
     if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany' || relationshipType === 'manyToOne') { 
      json[key] = Ember.get(record, key).mapBy('id'); 
      // TODO support for polymorphic manyToNone and manyToMany 
      // relationships 
     } 
    } 
}); 

Dies hat den Trick und es hat gut funktioniert. Aber jetzt habe ich ein anderes Problem. Wenn ich andere Datensatz bearbeiten, alle id Verweise sind durch ganze Objekt wie folgt ersetzt: „

{"App.Post":{"records":{"0v66j":{"id":"0v66j","title":"post2","comments":[**{"message":"comment 1"}, 
{"message":"comment 2"}**]},"8nihs":{"id":"8nihs","title":"post3","comments":["b4v2b","dbki4"]}}}, 
"App.Comment":{"records":{"p31al":{"id":"p31al","message":"comment 1"},"tgjtj":{"id":"tgjtj","message":"comment 2"}, 
"b4v2b":{"id":"b4v2b","message":"comments3"},"dbki4":{"id":"dbki4", 
"message":"comments4"}}}} 

Kommentar refrences sollte Kommentare sein. [“ P31al“,‚tgjtj‘] wie dies aber die Ide werden als "Kommentare" ersetzt: [{"message": "kommentar 1"}]

+0

Kann man den Kommentar nur dynamisch aktualisieren? Anstatt das gesamte Json-Objekt zurückzugeben? – yardpenalty

Antwort

-1

Ich habe ein paar Dinge in meinem Weg mit Ember .. und besonders Ember-Daten.

Einer von ihnen ist, wenn ich mit Vereinigungen beschäftigt bin, die ich manuell in den Vereinigungen wieder hinzufügen musste, die a speichern Sie müssen erneut speichern und addObject zu speicherinternen Zuordnungen verwenden, wenn Sie hier ein Bit verwenden. :)

Beachten Sie, dass dies in der Regel nur geschieht, wenn ich mehr als ein neues Objekt auf einmal aktualisiere. Zum Beispiel, wenn Ihr Beitrag neu ist und Ihr Kommentar auch neu ist.

Ich bin ein wenig besorgt, den folgenden Code in Ihrer Codebasis zu sehen, weil es nicht dort sein sollte. Sie sollten niemals Null- oder Nicht-Array-Objekte in Ihren Zuordnungen haben. Ich bin mir nicht sicher, was Hacks Sie mit dem Adapter tun und warum es notwendig war, aber ich hoffe, dass nicht der Grund war:

if(comments.get('content') == null) 
    comments.set('content', []); 

Wie auch immer, der folgende Code ist, wie ich würde wahrscheinlich Ihre Aktion erstellen schreiben. Es könnte helfen. Ich hoffe es tut es.

create: function() { 
    // get the post for association on the new comment 
    var post = this.get('post'); 

    // get the message to store on the new comment 
    var message = this.get('newMessage'); 

    var comment = this.store.createRecord('comment', { 
    message : message, 
    post : post 
    }); 

    comment.save().then(function(savedComment) { 
    post.get('comments').addObject(savedComment); 
    }); 
} 

Beachten Sie, dass es viel einfacher ist. Im Allgemeinen, wenn Sie knifflige komplizierte Dinge tun, ist etwas nicht in Ordnung und es ist Zeit, zu den Grundlagen zurückzukehren und eine Sache nach der anderen hinzuzufügen, gründlich zwischen Additionen zu testen. :)

Viel Glück!

+2

Hat das Ihrem Problem geholfen? Wie gehts? –

1

Wenn ApplicationSerializer verwendet wird, der LSSerializer erweitert, scheint es zu funktionieren.

Vielleicht wurde es behoben, seit gefragt?

Verwandte Themen