将多个模型的对象的集合作为Ember.js中模板中的可迭代内容 [英] Collection of objects of multiple models as the iterable content in a template in Ember.js

查看:73
本文介绍了将多个模型的对象的集合作为Ember.js中模板中的可迭代内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用Ember构建博客应用程序。我有不同类型的文章,书签,照片的模型。我想显示由用户创建的内容的流,我将需要所有这些模型的对象的集合,按照它们都具有publishtime的共同属性的降序排列。如何做到这一点?



我尝试过像

  StreamRoute = Ember.Route.extend({
model:function(){
stream = App.Post.find();
stream.addObjects(App.Bookmark.find());
stream.addObjects(App.Photo.find());
返回流;
}
}

资源名称为



但它没有我正在使用最新发布的Ember 1.0.0 rc 2和handlebars 1.0.0 rc 3与jQuery 1.9.1和ember-data。



可能是方法我试图实现这个整个事情是错误的,问题是即使我能够使用多个模型的对象的集合来遍历模板,我仍然需要区分每个对象的类型以显示它属性除了'publishtime'的共同属性。

解决方案

您可以使用计算属性以组合各种数组,然后使用内置的排序排序组合结果。



组合数组并排序它们



计算属性以组合多个数组:

  stream:function(){
var post = this.get('post'),
bookmark = this.get('bookmark'),
photo = this获得( '照片');

var stream = [];

stream.pushObjects(post);
stream.pushObjects(书签);
stream.pushObjects(photo);
返回流;
} .property('post'@ each','bookmark。@ each','photo。@ each'),

对包含所有项目的结果计算属性进行排序的示例:

  // https:// developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort 
streamSorted:function(){
var streamCopy = this.get('stream')。slice() ; // copy so原来不改变当排序
返回streamCopy.sort(function(a,b){
return a.get('publishtime') - b.get('publishtime') ;
});
} .property('stream。@ each.publishtime')
});



根据属性或其类型呈现项目



我知道有两种方法:


  1. 为每个对象添加布尔属性,并使用句柄 {{if}} 以检查该属性并呈现正确的视图

  2. 扩展 Ember.View 并使用计算属性根据正在呈现的对象类型来转换哪个模板(基于使用Ember.js按模型类型/对象值选择查看模板



方法1



JS:

  App.Post = Ember.Object.extend({
isPost:true
});

App.Bookmark = Ember.Object.extend({
isBookmark:true
});

App.Photo = Ember.Object.extend({
isPhoto:true
});

模板:

 code>< UL> 
{{#each item in controller.stream}}
{{#if item.isPost}}
< li> post:{{item.name}} {{item.publishtime }}< /锂>
{{/ if}}
{{#if item.isBookmark}}
< li>书签:{{item.name}} {{item.publishtime}}< /李>
{{/ if}}
{{#if item.isPhoto}}
< li>照片:{{item.name}} {{item.publishtime}}< /李>
{{/ if}}
{{/ each}}
< / ul>



方法2



JS: p>

  App.StreamItemView = Ember.View.extend({
tagName:li,
templateName:function (){
var content = this.get('content');
if(content instanceof App.Post){
returnStreamItemPost;
} else if (App.Photo的实例){
返回StreamItemBookmark;
} else if(content instanceof App.Photo){
返回StreamItemPhoto;
}
}。 property(),

_templateChanged:function(){
this.rerender();
} .observes('templateName')
})

模板:

 < UL> 
{{#each item in controller.streamSorted}}
{{view App.StreamItemView contentBinding = item}}
{{/ each}}
< / ul>

JSBin示例 - 未排序的列表使用方法1呈现,排序列表使用方法2呈现


I am trying to build a blog application with Ember. I have models for different types of post - article, bookmark, photo. I want to display a stream of the content created by the user for which I would need a collection of objects of all these models arranged in descending order of common attribute that they all have 'publishtime'. How to do this?

I tried something like

App.StreamRoute = Ember.Route.extend({
    model: function() {
        stream = App.Post.find();
        stream.addObjects(App.Bookmark.find());
        stream.addObjects(App.Photo.find());
        return stream;
    }
}

where the resource name is stream

But it doesn't work. I am using the latest released Ember 1.0.0 rc 2 and handlebars 1.0.0 rc 3 with jQuery 1.9.1 and ember-data.

Probably the way I am trying to achieve this whole thing is wrong. The problem is even if I am able to use the collection of objects of multiple models to iterate in the template, I would still need to distinguish between the type of each object to display its properties apart from the common property of 'publishtime'.

解决方案

You can use a computed property to combine the various arrays and then use Javascript's built in sorting to sort the combined result.

Combining the arrays and sorting them

computed property to combine the multiple arrays:

  stream: function() {
    var post = this.get('post'),
        bookmark = this.get('bookmark'),
        photo = this.get('photo');

    var stream = [];

    stream.pushObjects(post);
    stream.pushObjects(bookmark);
    stream.pushObjects(photo);
    return stream;
  }.property('post.@each', 'bookmark.@each', 'photo.@each'),

example of sorting the resulting computed property containing all items:

  //https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort
  streamSorted: function() {
    var streamCopy = this.get('stream').slice(); // copy so the original doesn't change when sorting
    return streamCopy.sort(function(a,b){
      return a.get('publishtime') - b.get('publishtime');
    });
  }.property('stream.@each.publishtime')
});

rendering items based on a property or their type

I know of two ways to do this:

  1. add a boolean property to each object and use a handlebars {{#if}} to check that property and render the correct view
  2. extend Ember.View and use a computed property to switch which template is rendered based on which type of object is being rendered (based on Select view template by model type/object value using Ember.js)

Method 1

JS:

App.Post = Ember.Object.extend({
  isPost: true
});

App.Bookmark = Ember.Object.extend({
  isBookmark: true
});

App.Photo = Ember.Object.extend({
  isPhoto: true
});

template:

<ul>
  {{#each item in controller.stream}}
      {{#if item.isPost}}
        <li>post: {{item.name}} {{item.publishtime}}</li>
      {{/if}}
      {{#if item.isBookmark}}
        <li>bookmark: {{item.name}} {{item.publishtime}}</li>
      {{/if}}
      {{#if item.isPhoto}}
        <li>photo: {{item.name}} {{item.publishtime}}</li>
      {{/if}}
  {{/each}}
   </ul>

Method 2

JS:

App.StreamItemView = Ember.View.extend({
  tagName: "li",
  templateName: function() {
    var content = this.get('content');
    if (content instanceof App.Post) {
      return "StreamItemPost";
    } else if (content instanceof App.Bookmark) {
      return "StreamItemBookmark";
    } else if (content instanceof App.Photo) {
      return "StreamItemPhoto";
    }
  }.property(),

  _templateChanged: function() {
        this.rerender();
    }.observes('templateName')
})

template:

<ul>
{{#each item in controller.streamSorted}}
    {{view App.StreamItemView contentBinding=item}}
{{/each}}
 </ul>

JSBin example - the unsorted list is rendered with method 1, and the sorted list is rendered with method 2

这篇关于将多个模型的对象的集合作为Ember.js中模板中的可迭代内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆