mercredi 16 décembre 2015

Ember ember-views.render-double-modify deprecation

I am trying to eliminate a deprecation that I recently introduced into my code and I need some help.

The deprecation is:

You modified ... twice in a single render. This was unreliable in Ember 1.x and will be removed in Ember 2.0 [deprecation id: ember-views.render-double-modify]

What I'm trying to do is display a list of scores and then the total of the scores. I need to drop the lowest score and not include it into the calculated total. I have this working. The deprecation comes when I try to add a CSS class via the classNameBindings to the score that has been excluded.

I'm pretty sure this is happening when I am doing the Ember.set during my computed property of calculatedTotal.

My question is how else can I keep the total score updated with the CSS also updated when I change a score in the form ?

code details: I have two components; score-row and judge-row. Score-row takes in an array of score objects, loops through each score calling the judge-score component.

Ember      : 2.2.0
Ember Data : 2.2.1

index.js - (mocked code pulled out for this question)

let scores = new Ember A();
scores.pushObject(Ember.Object.create({ points: 1 }));
scores.pushObject(Ember.Object.create({ points: 2 }));
scores.pushObject(Ember.Object.create({ points: 3 }));

index.hbs

{{score-row scores=scores}}

score-row.hbs

{{#each scores as |score|}}
    {{judge-score score=score}}
{{/each}}

{{calculatedTotal}}

score-row.js:

calculatedTotal: Ember.computed('scores.@each.points', () => {
    let totalScore = 0,
        scores = this.get('scores');

    if(Ember.isPresent(scores)) {
        var i,
            scoresLength = scores.length,
            sortedAscending,
            numLowToDrop = 1;

        sortedAscending = this.get('sortedScores');

        for(i = 0; i < scoresLength; i++) {
            currentScoreObj = sortedAscending.objectAt(i);

            // I think this is what is causing the ember-views.render-double-modify
            Ember.set(currentScoreObj, '_droppedLow', (i < numLowToDrop));
        }

        sortedAscending.forEach((score) => {
            if( !score.get('_droppedLow') ) {
                totalScore += +score.get('points');
            }
        });
    }
    return totalScore;
}),

// had to write my own sort because scores.sortBy('points') was sorting as if 
// points were a string and not a number ?
sortedScores: Ember.computed.sort('scores.@each.points', (score1, score2) => {
    if (+score1.get('points') > +score2.get('points')) {
        return 1;
    } else if (+score1.get('points') < +score2.get('points')) {
        return -1;
    }
    return 0;
})

judge-score.hbs

{{input value=score.points}}

judge-score.js

import Ember from 'ember';

export default Ember.Component.extend({
    classNameBindings: [
        "score._droppedLow:droppedLow"
    ]
});

Thanks!




Aucun commentaire:

Enregistrer un commentaire