如何将控制器更改正确绑定到模型?

时间:2014-12-18 09:53:52

标签: ember.js ember-data

我对Ember.js比较陌生,所以我给自己一个项目来解决问题。

我相信我理解这些基础知识。控制器包含state-logic,而模型包含model attribute-logic

在我的例子中,我有一组模型。这些模型包含一个表示另一个模型的id的属性:

App.Pokeball = DS.Model.extend({
    name: DS.attr('string'),
    rate: DS.attr('number'),
    pokemon: DS.belongsTo('pokemon')
});

我的控制器包含selectedPokemonIdselectedPokemon属性。当selectedPokemonId发生变化时,我想自动更新所有Pokeball模型。

我知道它很糟糕,但这是我用来更新模型的功能:

selectedPokemon: function(selectedPokemonId) {

    var pokemonId = this.get('selectedPokemonId'),
        store = this.store,
        id = 1,
        max = App.Pokeball.FIXTURES.length;

    for (id,max; id<= max;id++) {
        store.update('pokeball', {
            id: id,
            pokemon: pokemonId
        });
    }
    return store.find('pokemon', this.get('selectedPokemonId'));
}.property('selectedPokemonId'),

从技术上讲,这就是我需要的......但我确信我不是这样做的“蠢货方式”,必须有一种更简洁的方法来绑定控制器状态和模型之间的关系。

Github Example Code here

Working example

2 个答案:

答案 0 :(得分:1)

我认为做你想要完成的事情的“Ember方式”是使用观察者而不是属性:

... 

selectedPokemonObserver: function() {
    var pokemonId = this.get('selectedPokemonId'),
        store = this.store,
        id = 1,
        max = App.Pokeball.FIXTURES.length;

    for (id, max; id <= max; id++) {
        store.update('pokeball', {
            id: id,
            pokemon: pokemonId
        });
    }
}.observes('selectedPokemonId'),

selectedPokemon: function() {
    return this.store.find('pokemon', selectedPokemonId);
}.property('selectedPokemonId'),

...

答案 1 :(得分:1)

我喜欢直接使用模型作为对象,而不是管理记录ID。这样做可以大大简化您的代码。以下是我将如何实现这一目标。

首先,您的路线应使用模型钩子返回您要使用的所有模型。

路线的模型钩子应该类似于:

model: function()
{
    return Ember.RSVP.hash ({
        pokeballs: this.store.find('pokeball'),
        pokemon: this.store.find('pokemon') 
    });
}

通常,您希望在路由模型挂钩中执行store.find调用,因为它们可以是异步的(返回Promise),并且模型挂钩在继续之前等待promises解析。这可确保您的数据始终可供控制器使用。更多信息:http://emberjs.com/guides/models/finding-records/。请注意,我们正在使用的模型是一个具有两个属性的对象,pokeballs和pokemon,它们都是表示商店中所有相应对象的集合。

在控制器中,您可以直接引用selectedPokemon模型对象,而不是selectedPokemonId。然后,您可以使用&#39;观察&#39;观察对selectedPokemon的更改。然后简单地在每个pokeball上设置selectedPokemon并保存每个pokeball模型以将其持久保存回商店。如果你只是使用灯具,你甚至可以在没有保存每个pokeball的情况下逃脱,因为在模型对象上设置一个属性足以在商店中更改它。

selectedPokemonObserver: function()
{ 
    var thePokemonToSet = this.get('selectedPokemon');

    this.get('pokeballs').forEach( function( aPokeball ) { // note you can also do this.get('model.pokeballs') since the model is an object with two properties, pokeballs and pokemon
       aPokeball.set('pokemon', thePokemonToSet); //note that instead of an id, i'm setting the pokemon model object here to satisfy the belongsTo relationship
       aPokeball.save(); // you might not need this if using only fixtures and not persisting to db.
    });

}.observes('selectedPokemon')

模板中引用这些模型对象的任何内容都将自动更新。