Ich habe folgendes Modell:Bindung an ein verschachteltes Modell in Ember.js
App.Checklist = DS.Model.extend({
name: DS.attr('string'),
checkitems: DS.hasMany('App.Checkitem', { embedded: true }),
remainingItemsCount: function() {
var checkitemsToCount = this.get('checkitems');
return checkitemsToCount.filterProperty('isDone', false).get('length');
}.property()
});
ich will, um eine Liste von Checklisten zur Anzeige mit einer Zählung der aktuellen checkitems für jede Liste offen bleibt.
Wenn ich folgendes in eine Vorlage fallen, erhalte ich die richtige Ausgabe:
{{#each checklists}}
{{this.name}}
{{this.remainingItemsCount}}
{{/each}}
Wenn jedoch eine neue CheckItem zu einer Checkliste hinzugefügt wird, wird die Zählung nicht steigen.
ABER, wenn ich die berechnete remainingItemsCount
Eigenschaft in dem Checklist-Modell ändern, so dass es auf [email protected]
abhängt, dann wird die Zählung erhöht, wenn neue Checkitems hinzugefügt werden.
Das Problem ist, dass, sobald diese Abhängigkeit hinzugefügt wird, die Sammlung von untergeordneten checkitems falsch ist - es wiederholt das erste checkitem für die Anzahl der gesamten checkitems (dh wenn es fünf Elemente gibt, für die isDone falsch ist und vier, für die 'isDone' wahr ist, dann erscheint die Liste als 9, und das erste checkitem wird 9 mal wiederholt).
Was mache ich falsch?
UPDATE:
Es stellt sich heraus, dass die Abhängigkeit der remainingItemsCount Eigenschaft Hinzufügen verursacht glut-Daten einen neuen Aufruf an den Server zu machen.
Ohne die Abhängigkeit, werden die folgenden XHR-Anforderungen auf Seite Last gemacht:
GET http://localhost:3000/checklists
Mit der Abhängigkeit werden auf Seite laden folgende XHR Anfragen:
GET http://localhost:3000/checklists
GET http://localhost:3000/checkitems
Die letzte Anfrage kommt mit den folgenden Parametern, die eine Darstellung des ersten Check-Items zu sein scheinen, eingewickelt in einem "IDs" -Hash:
Ich frage mich, ob dies daran liegt, dass das Modell checkitem
mit einem Attribut "answerTo" definiert ist?
App.Checkitem = DS.Model.extend({
title: DS.attr('string'),
isDone: DS.attr('boolean'),
checklist: DS.belongsTo('App.Checklist')
});
UPDATE 2
Ich bin noch nicht sicher, warum, aber es ist klar, dass auf die Eigenschaft, die die Abhängigkeit Zugabe wie folgt ...
remainingItemsCount: function() {
var checkitemsToCount = this.get('checkitems');
return checkitemsToCount.filterProperty('isDone', false).length;
}.property('[email protected]').cacheable()
... verursacht ember -datas eingebauter DS.RESTAdapter zum Aufruf von findMany. Die Anfrage findMany sollte ein Array von IDs verwenden, stattdessen wird ein Array mit einem gesamten checkitem-Objekt, das in einem Hash mit dem Schlüssel 0 verschachtelt ist, an dieses übergeben.
SOLUTION
Am Ende habe ich verfolgt das Problem auf den folgenden Beobachter tief in glut-Daten:
dataDidChange: Ember.observer(function() {
var associations = get(this.constructor, 'associationsByName'),
data = get(this, 'data'), store = get(this, 'store'),
idToClientId = store.idToClientId,
cachedValue;
associations.forEach(function(name, association) {
if (association.kind === 'hasMany') {
cachedValue = this.cacheFor(name);
if (cachedValue) {
var ids = data.get(name) || [];
var clientIds = Ember.ArrayUtils.map(ids, function(id) {
return store.clientIdForId(association.type, id);
});
set(cachedValue, 'content', Ember.A(clientIds));
cachedValue.fetch();
}
}
}, this);
}, 'data')
Zu der Zeit, dass Beobachter an der Linie return store.clientIdForId(association.type, id)
bekam, das Array ids
war ein Array von checkitem-Objekten, kein Array von id-Integern. Das Update war ziemlich einfach: return store.clientIdForId(association.type, id.id)
gibt ein Array von ID-Ganzzahlen zurück.
Das hat mir sehr geholfen! Vielen Dank. Es stellt sich heraus, dass das Hinzufügen der Abhängigkeit dazu führt, dass die ember-Daten die URL des "/ checkitems" des Servers mit einem Hash aufrufen, der eines der checkitems darstellt. Ich habe keine Ahnung warum, aber das ist mit ziemlicher Sicherheit der Grund, warum der ArrayProxy von Checkitems falsch auftaucht. – sirvine
Ich frage mich, ob dies daran liegt, dass das Checkitem-Modell ein 'checklist: DS.belongsTo ('App.Checklist') 'Attribut hat. Ich kann nicht herausfinden, warum der Server angerufen werden würde. Ich habe nie eine URL für das Checkitem DS.Model gesetzt. – sirvine
Aber Sie verwenden einen 'DS.RESTAdapter'? Da diese Ihre URL automatisch abbildet. Vielleicht bekommst du deswegen einen Anruf auf deinen Server. – pangratz