将多个模型的对象的集合作为Ember.js中模板中的可迭代内容 [英] Collection of objects of multiple models as the iterable content in a template in Ember.js
问题描述
我尝试过像
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')
});
根据属性或其类型呈现项目
我知道有两种方法:
- 为每个对象添加布尔属性,并使用句柄
{{if}}
以检查该属性并呈现正确的视图 - 扩展
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:
- add a boolean property to each object and use a handlebars
{{#if}}
to check that property and render the correct view - 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屋!