我正在尝试创建一个emberjs应用程序,但我很难找到创建我想要的ui的最佳方法。我希望有一个具有向下钻取选择组件的应用程序,并且在某个级别时,允许用户选择一个项目并将其添加到他们的桶/购物车。高级别的想法是让itemGroups位于顶层,然后是每个项目组中的项目(2个级别现在就足够了)。
我有以下jsfiddle给出了一个简单的例子。在这个例子中,我有我的组,然后在我的桶下面。我想要做的是当我点击一个组更新视图的那一部分来显示该组中的项目。
一旦我拥有了最终我想让用户选择这些项目并添加到他们的桶中。实质上,用户可以遍历组/项层次结构以选择要添加到其存储桶的项目。
我确信我过于复杂,但我不确定如何继续这样做。
HTML
<script type="text/x-handlebars" data-template-name="application">
<h1> ember - latest jsfiddle </h1>
{{itemGroup}}
<br>
<br>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<h2> Bucket Items: </h2>
<div>{{model}}</div>
</script>
<script type="text/x-handlebars" data-template-name="itemGroup">
<h2> Groups </h2>
{{#each ig in controllers.itemGroup }}
<div class="buttonlink">{{ig}}</div >
{{/each}}
</script>
JS
App = Ember.Application.create({});
App.ApplicationController = Ember.ObjectController.extend({
needs: "itemGroup",
itemGroup: Ember.computed.alias("controllers.itemGroup")
});
App.ItemGroupController = Ember.ArrayController.extend();
App.ItemGroupView = Ember.View.extend({
templateName: 'itemGroup',
click:function(){
alert('i should replace the item group view with item details');
return false;
}
});
Ember.Handlebars.helper('itemGroup', App.ItemGroupView);
App.IndexRoute = Ember.Route.extend({
model: function () {
return "my bucket"
},
setupController: function (controller, model) {
this._super(controller, model);
this.controllerFor('itemGroup').set('model', ['group a', 'group b', 'group c', 'group d']);
}
});
更新
请参阅this fiddle我根据通过直升机评论找到的一些内容更新了我的原始示例。我想只用组中的项更新groups部分,并离开bucket部分,我的路由将基于桶来加载桶的当前状态,然后允许用户钻取组/项,最新的更新显示了我的想法。
我可以让它发挥作用,我不确定这是否是进行此类交互的'余烬'方式,或者是否有更惯用的方式。
答案 0 :(得分:2)
注意:对于冗长的回答道歉,但我认为这样做很好,因为这是一个非常常见的用例,这对任何刚接触Ember(和Ember Data)的人都有帮助。
在我看来,以下是在Ember和Ember数据中实现场景的最佳方式:
为application
设置模板(其他所有内容都将呈现在此路由的{{outlet}}
中),groups
(此模板将包装所有与群组相关的内容),{{1 (显示所有组的列表)和groups/index
(显示一个组)。
group
在你的JS中你然后设置你的商店。为了测试,我使用了<script type="text/x-handlebars" data-template-name="application">
<h1> ember - latest jsfiddle </h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="groups">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="groups/index">
<h2> Groups </h2>
{{#each group in content }}
<div class="buttonlink">
{{#link-to "group" group}}{{group.name}}{{/link-to}}</div>
</div >
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="group">
<h2>{{name}} Items</h2>
{{#each item in items}}
<div class="buttonlink">
{{item.name}}</div>
</div >
{{/each}}
<br />
{{#link-to "groups.index"}}Back to groups{{/link-to}}
</script>
,它允许我直接在我的JS中指定数据用于测试目的。最后,您需要将此替换为DS.FixturesAdapter
之类的内容,以便与您的后端进行通信。
DS.RESTAdapter
然后我们使用Ember Data指定我们的模型:
App = Ember.Application.create({});
App.Store = DS.Store.extend({
revision: 13,
adapter: DS.FixtureAdapter
});
为了简洁起见,我省略了灯具数据,但你可以在下面的jsFiddle中看到它。 App.Group = DS.Model.extend({
name: DS.attr('string'),
items: DS.hasMany('item', { async: true }),
});
App.Item = DS.Model.extend({
name: DS.attr('string'),
group: DS.belongsTo('group'),
});
告诉Ember Data父(App.Group)和子(App.Item)模型是异步加载的(即不一定是同时加载)。
下一步,我们定义应用程序中的路由。对于这个例子,我们只关心群体 - 特别是查看所有群体和个体群体。
{ async: true }
现在要做的就是告诉Ember在输入每条路线时该做什么:
App.Router.map(function() {
this.resource('groups', function() {
this.resource('group', { path: '/group/:group_id' });
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('groups.index');
}
});
路由是应用程序的默认路由(将其视为“主页”路由)。在我们的例子中,我们希望直接转到组列表,因此我们重定向到App.Index
。
groups.index
这将设置我们商店中所有组的路径模型。 Ember将自动检测到这是一个数组,并创建一个我们可以在该路由中使用的相应App.GroupsIndexRoute = Ember.Route.extend({
model: function() {
return this.get('store').findAll('group');
}
});
- 但如果我们想添加其他功能,我们也可以覆盖它。
请注意,我们无需明确设置Ember.ArrayController
或App.GroupRoute
,因为Ember足够聪明,可以在后台为我们执行此操作(但是,如果需要,我们可以再次覆盖它到)。
请参阅this jsFiddle。
答案 1 :(得分:0)
执行此操作的最佳方式取决于您的使用案例。一种方法是在模板中加载项目但隐藏它们,然后使用jQuery切换它们的可见性。
模板:
<script type="text/x-handlebars" data-template-name="itemGroups">
<h2> Groups </h2>
{{#each ig in controllers.itemGroup }}
{{itemGroup}}
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="itemGroup">
<div class="buttonlink">
<div class="group">{{ig.name}}</div>
<div class="details hidden">{{ig.items}}</div>
</div >
</script>
查看:
App.ItemGroupView = Ember.View.extend({
templateName: 'itemGroup',
click:function(){
this.$('.details, .group').toggleClass('hidden');
return false;
}
});
CSS:
.hidden {
display: none;
}