Ember.js - 如何定位在嵌套/重复浏览网点,什么都是这样的UI布局的最佳实践?(Ember

2019-08-04 06:18发布

我正在重构继承灰烬应用程序,具有相当多的非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} 

这到底是怎么做事的首选方式灰烬? 是否有任何开销创建不一定在任何时候都可以连接插座?

Answer 1:

好吧,时间和与此玩耍小时后,它似乎最有条件包括一个名为出口在上面直接嵌套我的观点的水平。

这是因为你需要一个单一的,可靠的出口在模板中的目标,并且似乎没有成为一个很好的方式来命名程序在运行时的出口。

此外,您希望的目标需要出口到路由器,控制器,以及用于渲染画面的当前状态呈现模板嵌套父模板中的某个地方。 如果出口尚未到位,由家长路由对象,你不能指望它的目标在你的叶节点路径。

让我用一个例子说明:

因为我本来问我的问题,我们的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?