0

我花了大约 10 天的时间来解决一个使用 Dojo 可以在大约 10 分钟内解决的简单问题。我希望我错过了一些简单的东西——我是一个想使用 Ember 的菜鸟。

我只是尝试使用 EmberData 使用来自另一个控制器的数据填充 Ember.Select 的内容。考虑这种情况:能够为原料选择一个食品组。

在 RawIngredientController 和 FoodGroupsController 之间使用“需要”依赖项并绑定内容似乎很清楚。

这是我最接近成功的一次,但对我来说还不够——我会解释的。

<script type="text/x-handlebars" data-template-name="rawIngredients">

     {{#each item in controller itemController="rawIngredient" }}

            {{! view Ember.Select
                    contentBinding="controllers.foodGroups.content"
                    optionValuePath="content.id"
                    optionLabelPath="content.name"
                    prompt="select Food Group" }}

     {{/each}}
</script>

Cook.RawIngredientController = Ember.ObjectController.extend({
    isEditing: false,
    needs: ['foodGroups'],
    ...
});


Cook.RawIngredient = DS.Model.extend({
    name: DS.attr('string'),
    nameKey: DS.attr('string'),
    foodGroup: DS.belongsTo('Cook.FoodGroup')
});

Cook.FoodGroupsRoute = Ember.Route.extend({
  setupController: function(controller) {
     controller.set('content', Cook.FoodGroup.all());  // have also tried find()
  }
});

Cook.FoodGroup = DS.Model.extend({
    name: DS.attr('string'),
    nameKey: DS.attr('string')
});

这实际上呈现所有 RawIngredients 没有错误,但 Selects 是空的,因为 FoodGroups 存储是空的。我可以导航到加载商店的 FoodGroups 屏幕,然后返回 RawIngredients,然后选择会填充 FoodGroups。

我已经看过很多关于这个问题的帖子,但是当涉及到 EmberData 时,没有一个能充分解决这个问题。有很多后加载示例,例如 pangratz http://jsfiddle.net/pangratz/hcxrJ/中的这个聪明示例 - 但我还没有发现任何使用 EmberData 来延迟加载内容的示例。

这篇文章非常接近 Ember.js:Ember.Select valueBinding 和延迟加载

并包含使用观察者的解决方法,我无法开始工作。我最终绑定到一个从未调用 FoodGroup 数据的实际加载的绑定。这是一个这样的尝试(可能是 20 多次)的示例,可能不是最好的示例:

Cook.FoodGroupsController = Ember.ArrayController.extend({
    ...
       // NOTE: This seems redundant
    values: function() {
        return this.get('content');
    }.property(),
    ...
});

Cook.RawIngredientController = Ember.ObjectController.extend({
    ...
    // this should be the instance; also tried the object name FoodGroupsController....also tried using needs + 'controllers.foodGroups.values' in the binding
    allFoodGroups: Ember.Binding.oneWay('Cook.foodGroupsController.values'),  '

    /*
    //  ... or rather ....??

    allFoodGroups: function() {
        this.get('foodGroupsBinding');
    },
    foodGroupsBinding: "Cook.foodGroupsController.values",
    */

    ...
});

        {{view Ember.Select
                contentBinding="allFoodGroups"
                optionValuePath="content.id"
                optionLabelPath="content.name"
                prompt="select Food Group" }}

但它错误地说“allFoodGroups”提供的是绑定而不是 Ember.Array。我想我迷失在纷繁复杂的命名约定的海洋中。我可以展示我的其他尝试,但都有未定义内容的错误。

啊。所以备份一下......至少使用我的原始解决方案并预加载 FoodGroups 商店应该提供一种解决方法,但是我似乎无法让 EmberData 以编程方式出去并加载数据。我在 RawIngredientController 中尝试了一个 init() 函数,例如

init: function() {
    var item = this.get('controllers.foodGroups.content.firstObject');
},

但我也没有找到合适的组合。即使我这样做了,这似乎也是错误的方法,因为这将为每个 RawIngredient 设置一个参考,而不是使用 RawIngredients(或 FoodGroups?)的单个参考 - 但这似乎是一个不同的话题。

这是我尝试用小提琴描述问题http://jsfiddle.net/jockor/Xphhg/13/

有没有人想出一种有效的方法来加载和使用在其他控制器中定义的存储,使用 EmberData 来延迟加载相关的内容?

4

1 回答 1

0

您的基本问题似乎是您没有访问 foodGroups 路由,因此它的 setupController() 永远不会被执行,因此选择控制器的内容永远不会被设置。

在您的示例中,当添加指向相关路由的链接并单击它时,路由将被初始化并且绑定工作。

我试图更新你的 JSFiddle,但它链接到来自 Github 的“最新”版本的 ember-data,该版本有一段时间没有更新(你应该自己构建它,直到他们发布正式版本),它是还使用旧版本的 Ember,所以我遇到了一些奇怪的错误。

所以这里有一个带有最新 Ember 和 Ember-data 的版本:http: //jsfiddle.net/tPsp5/

请注意单击“国家/地区”链接时会发生什么。我留下了一些debugger;可以帮助你理解什么时候被调用的语句。


作为设计说明,您的“父”控制器可能不应该依赖于“子”控制器。

于 2013-04-07T13:00:18.647 回答