使用 getJSON 获取数据的模板中的条件

Conditionals in templates with data fetched with getJSON

我想弄清楚如何做一些非常简单的事情:在模板中使用条件语句,并使用 getJSON 获取数据。我需要根据 JSON 散列上的 type 键显示信息。例如,我包含了一个 HBS 文件,其中包含我想做的事情。 Ember Way™ 是什么?

公司航线:

// routes/company.js

import Ember from 'ember';

export default Ember.Route.extend({
    model: function(params) {
        return this.store.findRecord('company', params.company_slug);
    },
    setupController: function(controller, model) {
        this._super(controller, model);

        Ember.$.getJSON('/companies/%@/events.json'.fmt(model.get('slug'))).then(data => {
            controller.set('events', data);
        });
    }
});

公司展示模板以及我想做的事情的示例:

<ul class="test">
    <li>lol</li>
    {{#each events as |event|}}
        <li class="{{event.type}}">
            {{event.title}}

            {{!-- This code will obviously not work: --}}
            {{#if event.type == 'company_event'}}
               show company event stuff
            {{/if}}
            {{#if event.type == 'user_event'}}
               show user event stuff
            {{/if}}

        </li>
    {{/each}}
</ul>

JSON 数据示例:

[
    {
        title: "test test test",
        type: "company_event",
        date: "2015-10-14T00:00:00.000+02:00"
    }
]

我能想到的有两个建议:

1。 http://emberobserver.com/addons/ember-truth-helpers

{{#if (eq event.type 'company_event')}}
  show company event stuff
{{/if}}

2.a。 {{component}}

您将有一个 company_event 和一个 user_event 组件(您需要将名称破折号化以符合命名规则),并执行类似的操作:

{{component event.type event}}

2.b。将它包装在一个组件中

组件的另一种可能性是将整个组件包装在组件中并使用计算属性:

{{#each events as |event|}}
  {{li-event event=event}}
{{/each}}

// components/li-event.js
export default Ember.Component.extend({
  tagName: "li",
  classNameBindings: ['event.type'],

  isCompanyEvent: Ember.computed.equal('event.type', 'company_event'),
  isUserEvent: Ember.computed.equal('event.type', 'user_event')
});

// templates/components/li-event.js
{{event.title}}

{{#if isCompanyEvent}}
  show company event stuff
{{/if}}
{{#if isUserEvent}}
  show user event stuff
{{/if}}

选择哪个选项留作 reader 的练习;)

event 定义为 Ember 对象,以便您可以在其上定义计算属性:

var eventObject = Ember.Object.extend({
  isCompanyEvent: Ember.computed.equal('type', 'company_event')
});

读入事件时,构建 Ember 个对象:

Ember.$.getJSON('/companies/%@/events.json'.fmt(model.get('slug'))) . 
  then(data => controller.set('events', data.map(event =>
    eventObject.create(event)));

然后

{{#if event.isCompanyEvent}}
     show company event stuff

Mustache 和 Handlebars 的开发人员有一个清晰的哲学观点,即他们广泛定义的业务逻辑不属于模板。他们的想法是"you prepare the data, I pump it out"。他们的 objective 首先是保持模板的简单性和可读性,但更重要的是将业务规则放在一个地方——最常见的是在控制器的等价物中。例如,event 对象的 type 属性 的可能值 "company_event" 具有某些特定的语义,在这种情况下,各种业务逻辑,因此 不属于 模板,其工作是制作一些 HTML。换句话说,这些开发人员希望避免这样一种情况,即对界面的每次更改都需要在 n 个不同的地方更改 n 个不同的东西.当然,没有开发人员愿意通过模板探索各种清单常量用于表示神奇事物的地方。这个问题更加相关,因为使用 JS 代码我们可以轻松地在模型、控制器或对象中添加逻辑来检测和报告 type 等字段的无效值,这更难,并且在实践并不常见,程序员可以将此类错误检测逻辑添加到模板中;如果他们这样做了,就很难将错误输出定向到任何有意义的地方。换句话说,模板没有等同于 assert.

这是一种非常啰嗦的说法,ember-truth-helpers 之类的东西是个糟糕的主意。进两步,退一步。在人们开始使用模板分离逻辑和内容十多年后,在允许 {{#if (eq.[=21 之类的新样式 Ember 助手等事物的纵容下,逻辑偷偷摸摸地回到内容中=]