过滤在Ember中有很多关联

时间:2014-12-16 05:00:12

标签: ember.js

我是Ember的新手,并坚持看似非常基本的东西。到目前为止,在我的电子商务应用程序中,我有两个模型,Product和Style;一个产品有很多样式。对于每种产品,我想列出样式的一个子集(例如,库存或缺货的样式)。来自Rails背景,我想我会在Product中创建一个名为stockedStyles的模型方法,它会过滤其样式并仅返回stocked = true的样式。这没用,所以我尝试了另一种使用控制器方法的方法,但也在那里打了一针。

以下是目前的代码:http://jsbin.com/mufumowabi/1/edit?html,js,console,output

虽然我肯定想知道这样做的最佳实践方法,但我也很好奇人们可以建议的其他方法,但不推荐 - 以及为什么不推荐它们。特别是当我正在学习新东西时,我喜欢了解你可以做某事的所有不同方式,然后选择最好/最干净的方式。

如果有一个涵盖此类内容的教程,请按我的方式发送。我找不到做这类事情的事情,尽管看起来很基本。

最后,我发现调试Ember有点像黑盒子。例如,对于此处发布的非工作代码,JS控制台只是说“错误”。关于如何获得有关我为什么做错的更多信息的提示也将非常受欢迎。

TIA, FANA

1 个答案:

答案 0 :(得分:0)

我感觉到你的痛苦。我也来自铁路背景,期望在实施中的相似性只是最初混淆。当他们声称Ember需要非常大的学习投资时,没有人会夸大其词,但如果你坚持下去就相信我是完全值得的。

真正的快速让我们来处理一个简单的问题:您可以将对象属性指定为Ember.computed或function(){/ *** /} .property('sdf');你不能两者兼得。因此,将该计算函数设为:

unstockedStyles: Ember.computed.filterBy('styles', 'stocked', false);

unstockedStyles: function() {
  return this.get('styles').filterBy('stocked', false);
}.property('styles.@each.stocked')

但你不能同时做到这两件事。

Ember模型与Rails模型

接下来,与来自rails视角的Ember的区别在于,Ember.js中的模型非常轻,仅用作数据源和框架之间的最小绑定。 Rails完全采用相反的方法,鼓励一个非常繁重的模型对象(这仍然是rails社区中争论的一个重要来源)。

在ember.js中,模型方法助手旨在放置在控制器对象中(同样,来自rails的反直觉)。搬出去,你会希望你的模型看起来像这样:

App.Product = DS.Model.extend({
  title: DS.attr(),
  styles: DS.hasMany('style', { async: true })
});

App.Style = DS.Model.extend({
  desc: DS.attr(),
  stocked: DS.attr("boolean")
});

与Rails的区别在于,Ember.js中控制器的作用是用于“装饰”对象,而在Rails中则用于处理传入/传出数据逻辑。对于每个页面,您可能希望以不同的方式呈现相同的数据。因此,模型将保持不变,并且控制器承担封装额外绒毛/计算的负担。您可以像在OO中教授继承模式一样考虑装饰,稍微扭曲一下:

假设你想要一个基类(你的Ember模型),然后你将它扩展到教师学生子类(您的控制器),以便添加可能来自相同类型但未以相同方式建模的附加属性。例如,教师和学生与课程有多对多的关系,但是您希望将学生建模为参加他们的课程,教师在这些课程中进行指导。控制器充当提供这种过滤器的方式。

ArrayController vs ObjectController

对于控制器,各个记录的计算属性应该放在ArrayController的相关ObjectController中(我们称之为ProductController),所以你的控制器现在看起来像这样:

App.IndexController = Ember.ArrayController.extend();

App.ProductController = Ember.ObjectController.extend({
    unstockedStyles: Ember.computed.filterBy('styles', 'stocked', true)
});

最后,虽然Ember.js可以自动将ObjectControllers与其关联的ArrayController关联到路由器中定义的资源,但是您在IndexController上加载了一个Product数组,因此您需要告诉IndexController使用ProductController来实现其项目行为: / p>

App.IndexController = Ember.ArrayController.extend({
  itemController: 'product'
});

App.ProductController = Ember.ObjectController.extend({
    unstockedStyles: Ember.computed.filterBy('styles', 'stocked', true)
});

把手绑定

除了一个小错误之外,这里并不多:当您在正确的控制器中正确启用计算属性时,您的{{#each}}循环将绑定到原始样式数组。将其更改为使用新属性:

{{#each unstockedStyles}}
  <li>
    {{desc}}, in stock: {{stocked}}
  </li>
{{/each}}

现在你很高兴去了!

JSBin修复程序:http://jsbin.com/sawujorogi/2/edit?html,js,output