【问题标题】:How to check type of object in Handlebars?如何检查把手中的对象类型?
【发布时间】:2014-06-12 18:12:00
【问题描述】:

我目前正在研究一个列出三种类型对象的搜索栏:用户、记录和位置。每个都有自己的模型,并且定义了相应的控制器。我需要做的是检查它是哪种类型的对象,因为我需要与它一起呈现的 HTML 不同。

{{#each mainUserSearchResults}}
              {{#link-to 'user' this.userID}}

                <div class="row mainListSeperator" {{action "getapplicantUserID" this target="view"}}>
                  <img class="applicantsIcon" src="">
                  <div class="applicantsName">
                    {{unbound this.firstName}}&nbsp;{{unbound this.lastName}}
                  </div>
                  <div class="applicantsTitle">
                    User
                  </div>
                </div>

              {{/link-to}}
            {{/each}}

我遇到的唯一问题是,如果它是用户,我需要它来打印 this.firstName 和 this.lastName,但我不能为记录这样做。对于记录,我必须以与执行 this.firstName 相同的方式呈现另一个属性 - this.recordID。执行此操作的方法是 if 条件,但我在 HandleBars 中找不到任何可以让我检查来自 mainUserSearchResults 的数据是用户还是记录的内容。

mainUserSearchResults 是我的控制器中的一个属性,它返回一个对象数组:目前它返回一个用户对象和记录对象的串联数组。

【问题讨论】:

    标签: object ember.js types handlebars.js


    【解决方案1】:

    Handlebars 是一个没有逻辑的模板,所以你真的不能执行计算,比如类型检查。 There are some pretty good reasons for this。如果是我,我会把这个责任推到别处,可能一直推到你的模型身上,原因有两个:

    1. 您在 DOM 中放置的任何条件都是 SLOW。当您使用速度较慢的设备(尤其是移动设备)时,问题只会变得更加复杂。
    2. 每次添加新的可搜索事物时,都必须更新模板。随着时间的推移,你最终会得到:

      {{#if ...}}
        ...
      {{/if}}
      
      {{#if ...}}
        ...
      {{/if}}
      
      {{#if ...}}
        ...
      {{/if}}
      
      {{#if ...}}
        ...
      {{/if}}
      

    代之以委托。例如,在您的用户模型中,添加

    formattedName: (function() {
      return [this.get('firstName'), this.get('lastName')].join(' ');
    }).property('firstName', 'lastName')
    

    对您的记录和位置执行相同的操作。

    然后,更改您的模板

    {{unbound this.firstName}}&nbsp;{{unbound this.lastName}}
    

    {{unbound this.formattedName}}
    

    现在,如果您在搜索中添加新类型,您将拥有一个完全通用的解决方案,只需要模型实现 formattedName 属性。

    有些人会说我的建议很糟糕,因为它混合了模型的业务逻辑职责和显示逻辑。在这种情况下,我猜你在不止一个地方显示 {{firstName}} {{lastName}},所以我认为保持代码 DRY 的好处超过将其移动到例如控制器。您的来电。

    【讨论】:

    • 非常感谢!我有点犹豫混合业务和显示逻辑,它也困扰着我,formattedName 属性需要额外的,但它似乎毫不费力地工作。至少就目前而言,这对我来说是最有效的方式。
    【解决方案2】:

    假设有某种方法可以轻松区分这 2 种以上类型的对象,您可以使用 if 语句并呈现不同的模板(甚至使用不同的部分模板,http://emberjs.com/guides/templates/rendering-with-helpers/

      <script type="text/x-handlebars" data-template-name="index">
        <ul>
        {{#each item in model}}
        <li>
    
        {{#if item.foo}}
          {{render 'foo' item}}
        {{/if}}
    
        {{#if item.cow}}
          {{render 'cow' item}}
        {{/if}}
        </li>
    
        {{/each}}
        </ul>
      </script>
    
    
      <script type="text/x-handlebars" data-template-name="foo">
        I'm a foo: {{foo}}
      </script>
    
      <script type="text/x-handlebars" data-template-name="cow">
        I'm a cow: {{cow}}
      </script>
    

    http://emberjs.jsbin.com/qinilege/1/edit

    或者,如果您需要更高级的检查,您可以使用项目控制器并在其中添加逻辑

    {{#each item in model itemController='checker'}}
      <li>
    
      {{#if item.isFooBar}}
        {{render 'foo' item.model}}
      {{/if}}
    
      {{#if item.isFooBaz}}
        {{render 'fooz' item.model}}
      {{/if}}
    
    
      {{#if item.isCow}}
        {{render 'cow' item.model}}
      {{/if}}
      </li>
    {{/each}}
    
    
    App.CheckerController = Em.ObjectController.extend({
      isFooBar: Ember.computed.equal('foo', 'bar'),
      isCow: Ember.computed.notEmpty('cow'),
      isFooBaz: Ember.computed.equal('foo', 'baz')
    });
    

    http://emberjs.jsbin.com/qinilege/2/edit

    【讨论】:

      猜你喜欢
      • 2011-01-27
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 2011-02-14
      相关资源
      最近更新 更多