我正在重构继承灰烬应用程序,具有相当多的非MVC的障碍给它的。 我期待让事情尽可能模块化,并且我希望能重复使用多个屏幕的各种UI组件,以帮助防止代码重复。
好像出口是做到这一点的最好办法。
现在,我有显示数量的元素,每个渲染使用模板化视图的UI。
{{#each item in controller}}
{{view App.ItemThumbView}}
{{/each}}
该视图的右侧栏是改变基于所述选择的出口。 当我选择一个项目,我想的模板化的子图,该选择时,通过嵌套出口揭示适当编辑UI中显示的编辑操作的列表。
实质上
+---------------------------------------------------+
| Parent Pane
|
| +------------------------------+ +----------+
| | Device Section | | Sidebar |
| | | | [Outlet] |
| | +--------+ +---------+ | | |
| | | Dev 1 | | Dev 2 | | | |
| | |[outlet]| | [outlet]| | +----------+
| | +--------+ +---------+ |
| +------------------------------+
+--------------------------------------------------+
嵌套视图的所有共享相同的控制器 - 这是有意义的 - 但我需要能够所选视图连接到其相应的插座。 我在连接插座的初步尝试从来没有显示。 该代码不会失败可言,因此控制器刚刚更新一个隐藏的出口。
如何定位在灰烬嵌套视图正确的出路何在? (充其量,我似乎能够击中边栏的出口,而不是一个嵌套设备模板内的插座。),这是摆在首位实现在烬上下文菜单结构合理?
*对于澄清我的当前设置,每个设备项目使用相同的模板呈现。 选择时,侧边栏出口将一些设备的元信息更新,而所选择的设备视图中也将其出口连接到编辑菜单。 只有一个设备项目将有它的“编辑”的出口连接在同一时间。
是否有意义,甚至在这里使用一个插座,或者我应该下降条件逻辑为模板,以显示编辑菜单的必要吗?
更新重申这个问题的最佳实践部分 :
奥特莱斯似乎为去耦元件,以及面向未来的电势图嵌套是巨大的。 但现在好像访问正确的出口嵌套的观点是有点麻烦。 此外,如果你总是知道什么成分(S)将被有条件地嵌套在模板中,这似乎只是easiestto硬编码的意见。 例如:
// within template used for individual result-list items
{{#if condition }}
{{view reusableSubView}}
{{/if}
这到底是怎么做事的首选方式灰烬? 是否有任何开销创建不一定在任何时候都可以连接插座?
好吧,时间和与此玩耍小时后,它似乎最有条件包括一个名为出口在上面直接嵌套我的观点的水平。
这是因为你需要一个单一的,可靠的出口在模板中的目标,并且似乎没有成为一个很好的方式来命名程序在运行时的出口。
此外,您希望的目标需要出口到路由器,控制器,以及用于渲染画面的当前状态呈现模板嵌套父模板中的某个地方。 如果出口尚未到位,由家长路由对象,你不能指望它的目标在你的叶节点路径。
让我用一个例子说明:
因为我本来问我的问题,我们的UI已经从设备列表改变的人的名单,但原理是一样的。
我有一个人用自己的照片列表,他们可以点击显示一些未来他们的结果更多的信息。
我有一个人的模板,看起来是这样的:
<script type="text/x-handlebars" data-template-name="people" >
<h3>People in this group</h3>
<div class="peeps">
{{#each controller}}
{{ view App.PersonView }}
{{#if selected }}
<div class='too-personal'>
{{ outlet veryPersonalDetails }}
</div>
{{/if}}
{{/each}}
</div>
</script>
而一个人的模板,有点像这样:
<script type="text/x-handlebars" data-template-name="person" >
{{#linkTo person this}}
<div data-desc="person-item" class="item">
<div class="portrait">
<img class="avatar" {{bindAttr src="gravatarUrl"}}/>
</div>
<div class="statuslabel"><span {{bindAttr class=":label statusLabel"}}>{{statusText}}</span></div>
<div class="cTitle">{{fullName}}</div>
</div>
{{/linkTo}} </script>
而细节有额外信息并修改选项模板
<script type="text/x-handlebars" data-template-name="person/details" >
various edit options
</script>
在点击一个人的结果,我的路由器拿起网址更新,并在细节存根模板到父人的模板。 我的路由器设置是这样的:
App.Router.map(function() {
...
this.resource('people', { path: '/people'}, function() {
this.resource('person', { path: '/:person_id' },
function() {
this.route('details');
}
);
});
});
随着个人路线:
App.PeopleRoute = Ember.Route.extend({
model: function() {
return App.People.find();
},
setupController: function(controller, model) {
controller.set('content', model);
}
});
App.PersonRoute = Ember.Route.extend({
model: function(params) {
return App.People.peepsById[params.person_id];
},
setupController: function(controller, model) {
this._super(controller, model);
var person = model;
// this block ensures that only one person has a selected status at a time
// ignore the overly-verbose code. I'm cleaning it up tomorrow
var ls = App.People.lastSelected;
if (ls) {
ls.set('selected', false);
}
person.set('selected', true);
App.People.lastSelected = person;
controller.set('content', model);
},
renderTemplate: function() {
// person is actually stored in router 'context' rather than 'model'
// omg!
var x = this.controllerFor('personDetails').set('content', this.get('context'));
this.render('person/details', { // render person/details
into:'people', // into the people template
outlet: "veryPersonalDetails", // at the veryPersonalDetails outlet
controller: x // using the personDetails controller for rendering
});
// additional rendering in sidebar outlet for testing
this.render('person/details',{
into:'people',
outlet: "personDetails",
controller: x
});
console.log("@@@ we did it!");
}
});
我原本想有PersonView内出口,但是这是行不通的,因为我一个人的模板竟是人的路线内呈现。 通过应用程序到达的人路线的时候,控制器已经呈现所有的人都在列表中。 个别人我想目标已经早就过去了。
通过具有路由充当父和所需子模板之间的中介,我能做到这一点。
最后,关于是否模板内显式声明嵌套视图,或只使用网点的问题,我认为出口是更干净。 虽然这种解决方案涉及了一下455元的工作,这是远远优于其过于复杂的模板对象。 现在,我希望能实现的模板任意复杂的嵌套不碰任何东西,但参与其渲染的路由。
此外,该解决方案消除了未使用的插座的开销。 我相信您应该只有您打算使用,而不是乱抛垃圾的“DOM”带着一帮空的容器对象的网点。
文章来源: Ember.js — How do I target outlets in nested/repeated views, and what are the best practices for such a ui layout?