2016-11-27 4 views
0

Je suis un débutant Ember, alors pardonnez-moi si j'ai manqué quelque chose d'évident (j'ai passé du temps googler ce problème et ne trouve toujours pas de solution), mais il me semble que Ember Les propriétés calculées ne fonctionnent pas comme documentées/destinées aux propriétés de tableau telles que length.Ember propriété calculée sur Array

Je suis en train de construire ma propre file d'attente:

// app/custom-objects/processing-queue-item.js 
import Ember from 'ember'; 

export default Ember.Object.extend({ 
    payload: null, 
    extraContext: null, 
    processingState: 'pending', // pending, succeeded, failed 
    processingOutcome: null, // null for pending, result for  succeeded, error for failed 

    toString() { 
    return `{ProcessingQueueItem: processingState=${this.get('processingState')}, processingOutcome=${this.get('processingOutcome')}, extraContext=${this.get('extraContext')}, payload=${this.get('payload')}}`; 
    } 
}); 

// app/custom-objects/processing-queue.js 
import Ember from 'ember'; 
import ProcessingQueueItem from './processing-queue-item'; 

export default Ember.Object.extend(Ember.Enumerable, { 
    queueName: null, 

init() { 
    this.set('items', []); 
    this.get('items'); 
    this.get('items.length'); 
    this.get('length'); // Force observation 
}, 

/* 
* Public API 
*/ 

enqueue(payload, extraContext = null) { 
let itemToEnqueue = ProcessingQueueItem.create({ payload: payload, extraContext: extraContext }); 

this.get('items').pushObject(itemToEnqueue); 
this.scheduleProcessing(); 

return itemToEnqueue; 
}, 

toString() { 
    return `{ProcessingQueue: queueName=${this.get('queueName')}, length=${this.get('length')}}`; 
}, 

/* 
    * Internal API 
    */ 

scheduleProcessing() { 
    Ember.run(() => { 
    this.maybeProcessAnItem(); 
    }); 
}, 

maybeProcessAnItem() { 
    console.log(`maybe process an item ${this}`); 
}, 

/* 
* Ember.Enumerable mixin 
*/ 

length: Ember.computed('items.length', function() { 
    return this.get('items.length'); 
}), 

nextObject(index, previousObject, context) { 
    return this.get('items').nextObject(index, previousObject, context); 
} 
}); 

Cette classe est incomplète, mais je veux commencer à afficher le contenu de la file d'attente dans un modèle pour faciliter le débogage, mais je ne peux pas obtenir que le travail . Voici mon contrôleur et le modèle:

// app/controllers/dashboard.js 
import Ember from 'ember'; 
import ProcessingQueue from '../custom-objects/processing-queue'; 

export default Ember.Controller.extend({ 
    init() { 
    this._super(...arguments); 
    this.set('processingQueue', ProcessingQueue.create({ queueName: 'DashboardQueue' })); 
    this.get('processingQueue'); 
    this.get('processingQueue.length'); 
    this.get('queueLength'); 
}, 

queueLength: Ember.computed('processingQueue.length', function() { 
    return this.get('processingQueue.length'); 
}), 
}); 

// app/templates/dashboard.hbs 
<h1>Dashboard</h1> 

<h2>Queue Length: '{{queueLength}}'</h2> 
{{#each processingQueue as |queueItem|}} 
<p>{{queueItem.payload}}</p> 
{{/each}} 

{{outlet}} 

Le problème est, dans la <h2>Queue Length: '{{queueLength}}'</h2>, la longueur de la file d'attente est toujours indéfinie jusqu'à ce que j'ajouter des éléments à la file d'attente. Mais ce n'est pas vrai, la file d'attente a un tableau vide et une longueur de 0. En utilisant $E à partir du contrôleur de tableau de bord de EmberInspector, je peux voir que $E.get('processingQueue.length') et $E.get('queueLength') sont tous les deux undefined. Ce qui est étrange, c'est que dès que j'ajoute des éléments dans la file d'attente, la longueur de la file d'attente est définie, 1, 2, 3, ... et continue et synchronise le modèle lorsque j'ajoute des éléments de file d'attente. Ainsi, le premier $E.get('processingQueue').enqueue('foo') met à jour automagiquement le modèle pour afficher une longueur de file d'attente de '0', puis '1' et ainsi de suite.

Pourquoi est-ce que ce n'est pas défini mais avant que j'ai mis en file d'attente des éléments? J'ai essayé d'ajouter tout autour de l'endroit selon Unconsumed Computed Properties Do No Trigger Observers mais cela ne semble pas aider.

Des idées? Il est tout à fait possible que je ne comprenne pas quelque chose sur les propriétés calculées ici, mais je ne comprends pas quoi et pourquoi ... J'ai essayé volatile(), [], @each et tout cela et je ne peux pas obtenir cela pour faire une différence non plus. Quelque chose ne va pas ...

Toute aide serait grandement appréciée et je serais prêt à ajouter au Wiki, écrire un article de blog et peut-être libérer ma file d'attente en tant que source ouverte en guise de remerciement. :-)

Merci! Et merci encore pour avoir rendu Ember si génial!

+0

Y at-il un peu de code manquant au sommet de votre exemple de code? –

+0

Je ne pense pas ... Que voulez-vous dire "code manquant"? J'ai eu quelques problèmes avec le S.O. le formatage du code (pourquoi ne supporte-t-il pas les blocs de code fencés?) mais je n'ai pas intentionnellement omis quoi que ce soit ... Je suis curieux de savoir ce que vous voulez dire? Merci! – Joel

+0

Voici l'EmberTwiddle si cela vous aide: https://ember-twiddle.com/2892b20ceb81e8655b628d2b6fabbb1d?openFiles=controllers.application.js%2C – Joel

Répondre

1

Je remplacerais les propriétés calculées comme

length: Ember.computed('items.length', function() { 
    return this.get('items.length'); 
}), 

avec des alias

length: Ember.computed.alias('items.length'),