2017-02-04 51 views
0

我是Ember的新手,正在使用Ember.js 2.10。我试图只使用组件而不是控制器。我试图创建一个组件,创建一个链接列表或只是项目的列表,并根据发送的属性排序或不排序。我有链接部分工作,但我似乎无法得到在不重复大量代码的情况下进行分类工作,这让我认为我做错了什么。我尝试将排序逻辑移入计算属性,但不起作用。如果我没有指定sortBy属性,它仍然会对列表进行排序。如果我确实指定为sortBy属性,我根本没有得到一个列表,并且console.log显示作为ComputedProperty返回的内容。基于if属性设置的ember.js组件排序模型

这似乎很基本,我不应该这样做,所以如果有一个Ember的方式做到这一点,我想知道。无论如何,我想了解我在做什么错误的学术价值。

app/components/column-list.js

import Ember from 'ember'; 

export default Ember.Component.extend({ 
    tagName: 'ul', 
    classNames: ['column-list'], 
    sortedItems: Ember.computed('items', 'sortBy', function() { 
    if (this.get('sortBy') !== undefined) { 
     let sd = [ this.get('sortBy') ]; 
     return Ember.computed.sort(this.get('items'), sd); 
    } else { 
     return this.get('items'); 
    } 
    }), 
}); 

app/templates/components/column-list.hbs

{{#if sortBy}} 
    {{#each sortedItems as |item|}} 
    <li> 
     {{#if link}} 
     {{#link-to link item.id}} 
      {{yield item}} 
     {{/link-to}} 
     {{else}} 
     {{yield item}} 
     {{/if}} 
    </li> 
    {{/each}} 
{{else}} 
    {{#each items as |item|}} 
    <li> 
     {{#if link}} 
     {{#link-to link item.id}} 
      {{yield item}} 
     {{/link-to}} 
     {{else}} 
     {{yield item}} 
     {{/if}} 
    </li> 
    {{/each}} 
{{/if}} 

app/templates/category/index.hbs

{{#column-list class="categories" sortBy="title" link="category.show" items=model as |i|}} 
    {{i.title}} 
{{/column-list}} 

mirage/fixtures/category.js

export default [ 
    { 
    id: 'main-dishes', 
    title: 'Main Dishes', 
    }, { 
    id: 'cakes-pies-and-sweets', 
    title: 'Cakes, Pies & Sweets', 
    }, { 
    id: 'langappie', 
    title: 'Langappie', 
    }, { 
    id: 'dips-and-sauces', 
    title: 'Dips & Sauces', 
    }, { 
    id: 'meat-dishes', 
    title: 'Meat Dishes', 
    }, { 
    id: 'vegetable', 
    title: 'Vegetable', 
    }, { 
    id: 'seafood-dishes', 
    title: 'Seafood Dishes', 
    }, { 
    id: 'bread-and-cereals', 
    title: 'Bread & Cereals', 
    } 
]; 

更新:

我在重组后玩弄的是@Jovica制成,我收到“断言失败:排序定义‘sortedItems’上必须是一个函数或字符串数​​组”,所以我觉得我仍然有错误。 Link to twiddle

UPDATE2:

我发现,我在我的玩弄一个错字,并得到它的正常工作。 new twiddle有正确的修复。现在要弄清楚为什么在没有我询问的情况下,ember-mirage会订购数据,但那是一个不同的问题。

+0

欢迎来到Stackoverflow!我建议你写一个[twiddle](https://ember-twiddle.com/),而不是粘贴一个长代码。通过这样做,许多回答者可以玩你的代码。 – ykaragol

+0

关于控制器,您可能需要阅读以下文档:http://emberjs.com/learn/#faq-future-proof https://guides.emberjs.com/v2.11.0/controllers/#toc_common-questions – locks

+0

@锁我明白,控制器将保持一些变化。此代码看起来像是组件的完美候选者,因为它可以在应用程序中重复使用很多次。你不同意吗?我只是想确保我理解你的评论。 –

回答

1

返还Ember.computed.sort宏没有做什么,你认为它是。你将不得不在Array类上使用排序方法。相关密钥也没有正确声明,如果要更新列表,它将是items.[]

这里有一个建议的解决方案,更新时则传递到组件的变化排序关键字排序:

export default Ember.Component.extend({ 
    appName: 'Ember Twiddle', 
    dishes: foo, 
    sortedItems: Ember.computed.sort('dishes', 'sortBy') 

    didReceiveAttrs() { 
    if (this.get('sortBy')) { 
     this.set('sortBy', [ this.get('sortBy') ]); 
    else { 
     this.set('sortBy', []); 
    } 
    } 
}); 

下面是你需要的,因为当sortBy是一个空数组模板,将计算出的宏将不排序阵列:

{{#each sortedItems as |item|}} 
    <li> 
    {{#if link}} 
     {{#link-to link item.id}} 
     {{yield item}} 
     {{/link-to}} 
    {{else}} 
     {{yield item}} 
    {{/if}} 
    </li> 
{{/each}} 
+0

只是为了让我明白你的解决方案和@ Jovica之间的区别在于,如果我通过一个新的sortBy而不必重新加载页面(如同一个排序按钮一种行为)?如果一个新的列表项被异步地添加到Ember Data中(web套接字或者某个东西)或者一个项目被重命名了,那么这个列表会自动被更新和排序,而另一个则不会(我知道Ember可以更新DOM数据发生变化,但我不知道该怎么做)? –

0

试试这个

sortedItems: Ember.computed('items', 'sortBy', function() { 
    if (this.get('sortBy') !== undefined) { 
    let sd = this.get('sortBy'); 
    return this.get('items').sortBy(sd); 
    } else { 
    return this.get('items'); 
    } 
}), 

或较短的版本

sortedItems: Ember.computed('items', 'sortBy', function() { 
    let sortTerm = this.get('sortBy'), 
     items = this.get('items'); 
    return Ember.isBlank(sortTerm) ? items : items.sortBy(sortTerm); 
} 
+0

我让它在[twiddle](https://ember-twiddle.com/1f66e42b3b9e906ae395885474e3483d?openFiles=templates.application.hbs%2Ctemplates.components.column-list.hbs)中工作,但我忘了这个'sortBy'方法在['Ember.Array'](http://emberjs.com/api/classes/Ember.Array.html#method_sortBy)..但我不确定是否返回'返回Ember.computed.sort'模式。这将永远不会工作,我们不应该那样做。我的假设是正确的? – kumkanillam

+0

@kumkanillam我不太确定,但我认为它可以使用,但没有必要,因为sortBy方法在这个例子中更合适。 –

+0

谢谢。在您的简短版本inclue返回结果 – kumkanillam