使用 Ember 进行导航的正确方法 [英] Right way to do navigation with Ember

查看:10
本文介绍了使用 Ember 进行导航的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

导航侧边栏的正确方式"是什么(或者至少是选项,如果没有单一的Ember 方式"可以做到这一点)?我应该以某种方式查看 ContainerViews,还是应该使用新的插座功能并将导航放在我的应用程序视图中?

此外,根据 URL 在 li 上设置 .active 类的正确方法"是什么(我正在使用路由)?有什么帮手吗?

解决方案

<更新日期="2013-01-16">

由于路由器 API 的最近更改,前面的示例不再有效,因此我不打算修复它们.所有使用旧路由器的应用程序应尽快迁移到最新版本.

这是一个更新的小提琴:来源 |现场演示

我会经常维护/修复/添加功能.

2013 年 4 月 3 日编辑:

替代示例 - WIP:来源 |演示

以下所有内容均已弃用

<更新>

2012 年 11 月 9 日

只需添加一个指向更好示例的链接,该示例还解决了在选择给定路线时 OP 希望在当前导航栏项中设置类的部分

JSFiddle 中的来源(点击这里 看它运行)

如果您查看 NavigationController,您将看到 'selected' 属性,我用它来检查子视图 NavigationItemView 的 isActive 方法.isActive 将根据同一视图(在模板中定义)的 menu 属性中的值和(控制器的)属性 selected 中的值返回 true 或 false).然后检查 classNameBinding 表达式,该表达式为该特定子项的类设置活动"或不设置.还要检查 ConnectOutlets,这是我将该导航项目标记为选中的位置.

这是在 ember-latest 上运行的.我还使用了一些 Ember.Bootstrap 以及一些原始的 TwitterBootstrap 功能/类/等(但我已经用 metro-bootstrap 替换了样式).

因为空间和其他原因,没有在这里粘贴整个内容.我将保留原始代码和相同的链接,以供参考原始问题/答案.

我会继续更新这个新样本只是因为 ember 很有趣 =)

This fiddle 从视图中显示静态导航栏,outlet仅用于内容展示,也可以直接到展示中查看运行

如您所见,您可以使用包含操作链接的简单视图,并在应用程序主视图中呈现该视图.开始"下的子路线还有一个迷你导航栏,来自类似的模板.

把手:

<script type="text/x-handlebars";数据模板名称=导航栏"><ul><li><a href=#";{{action gotoHome}}>Home</a></li><li><a href=#";{{action gotoStarting}}>开始使用</a></li><li><a href=#";{{action gotoCommunity}}>社区</a></li><script type="text/x-handlebars";数据模板名称=入门菜单"><ul><li><a href=#";{{action gotoIndex}}>概览</a></li><li><a href=#";{{action gotoMVC}}>关于MVC</a></li><li><a href=#";{{action gotoEmber}}>关于 Ember</a></li><script type="text/x-handlebars";数据模板名称=家"><h2>欢迎</h2><br/><img src="http://emberjs.com/images/about/ember-productivity-sm.png";alt=余烬标志"/><br/><br/><p>培根 ipsum dolor 坐 amet qui ullamco 练习, shankle 牛肉 sed 培根圆 kielbasa in. Prosciutto pig bresaola, qui 肉饼 ea 舌头 non dolore et 五花肉 andouille ribeye 排骨 enim.Enim exeritation elit,牛腩 nisi ex swine 在生涩的 consequat 熏牛肉 dolore sed 广告.在鼓槌牛,意大利腊肠猪肥背短肋火腿 ut in shankle consequat 咸牛肉 id.Deserunt 火腿牛肉斑点.</p><p>Do 牛肋骨 dolore 猪鸡腿,鹿肉官员 qui magna ea anim.生涩的小腿小腿,猪里脊舌头 commodo boudin elit cupidatat turducken id capicola 肉丸.牛排火腿飞节里脊肉,id 鸡腿肉干.Dolore veniam cillum minim,pariatur est 牛肉.Sunt fatback tri-tip exchuck.</p><br/><br/><strong>注意</strong>:这是一个没有<i>绑定</i>的基本模板.<script type="text/x-handlebars";数据模板名称=开始"><h2>Ember 入门</h2>{{查看 App.StartingMenuView}}<br/><br/><br/><p>培根 ipsum dolor 坐 amet qui ullamco 练习, shankle 牛肉 sed 培根圆 kielbasa in. Prosciutto pig bresaola, qui 肉饼 ea 舌头 non dolore et 五花肉 andouille ribeye 排骨 enim.Enim exeritation elit,牛腩 nisi ex swine 在生涩的 consequat 熏牛肉 dolore sed 广告.在鼓槌牛,意大利腊肠猪肥背短肋火腿 ut in shankle consequat 咸牛肉 id.Deserunt 火腿牛肉斑点.</p><p>Do 牛肋骨 dolore 猪鸡腿,鹿肉官员 qui magna ea anim.生涩的小腿小腿,猪里脊舌头 commodo boudin elit cupidatat turducken id capicola 肉丸.牛排火腿飞节里脊肉,id 鸡腿肉干.Dolore veniam cillum minim,pariatur est 牛肉.Sunt fatback tri-tip exchuck.</p><br/><br/><strong>注意</strong>:这是一个嵌入了菜单视图的基本模板<script type="text/x-handlebars";数据模板名称=关于-mvc"><h2>关于MVC</h2>{{查看 App.StartingMenuView}}<br/><br/><br/><p>模型-视图-控制器 (MVC) 是一种用于交互式计算机用户界面的软件设计,它将信息表示与用户与其交互分开. [1] [8]模型由应用程序数据和业务规则组成,控制器调解输入,将其转换为模型或视图的命令. [3]视图可以是数据的任何输出表示,例如图表或图表.相同数据的多个视图是可能的,例如用于管理的饼图和用于会计师的表格视图.</p>在<a href=http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"阅读更多信息.target=_blank">维基百科</a><br/><br/><strong>注意</strong>:这是一个嵌入了菜单视图的基本模板<script type="text/x-handlebars";数据模板名称=关于余烬"><h2>关于 Ember</h2>{{查看 App.StartingMenuView}}<br/><br/><br/><p>创建<strong>雄心勃勃</strong>的框架网络应用程序

在 <a href="http://emberjs.com/about/" 阅读更多内容.target=_blank">emberjs.com</a><br/><br/><p>培根 ipsum dolor 坐 amet qui ullamco 练习, shankle 牛肉 sed 培根圆 kielbasa in. Prosciutto pig bresaola, qui 肉饼 ea 舌头 non dolore et 五花肉 andouille ribeye 排骨 enim.Enim exeritation elit,牛腩 nisi ex swine 在生涩的 consequat 熏牛肉 dolore sed 广告.在鼓槌牛,意大利腊肠猪肥背短肋火腿 ut in shankle consequat 咸牛肉 id.Deserunt 火腿牛肉斑点.</p><p>Do 牛肋骨 dolore 猪鸡腿,鹿肉官员 qui magna ea anim.生涩的小腿小腿,猪里脊舌头 commodo boudin elit cupidatat turducken id capicola 肉丸.牛排火腿飞节里脊肉,id 鸡腿肉干.Dolore veniam cillum minim,pariatur est 牛肉.Sunt fatback tri-tip exchuck.</p><br/><br/><strong>注意</strong>:这是一个嵌入了菜单视图的基本模板<script type="text/x-handlebars";数据模板名称=社区"><h1>Ember 社区</h1><p>与社区取得联系</p><p>特色联系信息:</p>{{#内容中的每一项}}<a {{bindAttr href="item.linkUrl";}} 目标=_blank"><图像高度=32"宽度=32"{{bindAttr src="item.imageUrl";标题=item.displayName"alt=item.displayName"}}/>
{{item.displayName}}</a><br/>{{/每个}}<br/>在 <a href="http://emberjs.com/community/" 查看有关 ember 社区的更多信息.target=_blank">emberjs.com</a><br/><br/><strong>注意</strong>:这是一个带有<i>foreach</i>的模板.循环类型</脚本>

JavaScript:

App = Em.Application.create();App.ApplicationController = Em.Controller.extend();App.ApplicationView = Em.View.extend({模板名称:'应用程序'});App.HomeController = Em.Controller.extend();App.HomeView = Em.View.extend({模板名称:'家'});App.NavbarController = Em.Controller.extend();App.NavbarView = Em.View.extend({模板名称:'导航栏'});App.StartingController = Em.Controller.extend();App.StartingView = Em.View.extend({模板名称:'开始'});App.StartingMenuController = Em.Controller.extend();App.StartingMenuView = Em.View.extend({模板名称:'入门菜单'});App.AboutMVCController = Em.Controller.extend();App.AboutMVCView = Em.View.extend({模板名称:'关于-mvc'});App.AboutEmberController = Em.Controller.extend();App.AboutEmberView = Em.View.extend({模板名称:'关于余烬'});App.CommunityModel = Em.Object.extend({显示名称:空,链接网址:空,图片网址:空});App.CommunityController = Em.ArrayController.extend({内容: [],初始化:函数(){this._super();this.pushObject(App.CommunityModel.create({displayName: '推特',linkUrl: 'https://twitter.com/#!/emberjs',imageUrl: 'http://icons.iconarchive.com/icons/iconshots/social-media-network/32/twitter-icon.png'}));this.pushObject(App.CommunityModel.create({显示名称: 'GitHub',linkUrl: 'https://github.com/emberjs/ember.js',imageUrl: 'http://www.workinprogress.ca/wp-content/uploads/github.png'}));}});App.CommunityView = Em.View.extend({模板名称:'社区',contentBinding: 'App.CommunityController.content'});App.Router = Em.Router.extend({enableLogging: 真,位置:'哈希',根:Em.Route.extend({//事件gotoHome: Ember.Route.transitionTo('home'),gotoStarting: E​​mber.Route.transitionTo('starting.index'),gotoCommunity: Ember.Route.transitionTo('community.index'),//状态家:Em.Route.extend({路线: '/',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('home');}}),开始:Em.Route.extend({//设置路线:'/开始',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('starting');},//事件gotoMVC: Ember.Route.transitionTo('mvc'),gotoEmber: Ember.Route.transitionTo('ember'),gotoIndex: Ember.Route.transitionTo('index'),//状态索引:Em.Route.extend({路线: '/',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('starting');}}),mvc: Em.Route.extend({路线:'/mvc',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('aboutMVC');}}),余烬:Em.Route.extend({路线:'/余烬',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('aboutEmber');}})}),社区:Em.Route.extend({//设置路线:'/社区',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('community');},//事件//状态索引:Em.Route.extend({路线: '/',连接插座:功能(路由器,上下文){router.get('applicationController').connectOutlet('community');}})})})});App.initialize();

What's the "right way" (or at least the options, if there is no single "Ember way" of doing this) for a navigation sidebar? Should I be looking at ContainerViews somehow, or should I just use the new outlet feature and stick the navigation inside my application view?

In addition, what's the "right way" to set an .active class on an li depending on the URL (I'm using routing)? Is there some kind of a helper for this?

解决方案

<Update date="2013-01-16">

The previous examples are no longer valid since the recent changes in the Router API, so I'm not going to fix those. All applications using the old router should migrate as soon as possible to the latest.

Here's an updated fiddle: Source | Live Demo

I will be maintaining/fixing/adding features every so often.

Edit on Apr 3rd 2013:

Alternative Sample - WIP: source | demo

ALL CONTENT BELOW IS DEPRECATED

<Update>

2012-Nov-09

Just adding a link to a better sample that also addresses the part which the OP wants to set a class in the current navbar item when a given route is selected

Source in JSFiddle (Click here to see it running)

If you look in the NavigationController you'll see the 'selected' property, which I use to check in the isActive method of the child view NavigationItemView. The isActive will return true or false based on the value in the menu property of the same view (defined in the template) and the value in the property selected (of the controller). Then check the classNameBinding expressions which either sets 'active' or nothing to the class of that particular child. Also check the ConnectOutlets which is where I'm marking that nav item as selected.

This is running on ember-latest. I'm also using a little of Ember.Bootstrap as well as some of the original Twitter Bootstrap features/classes/etc (but I've replaced the styles with metro-bootstrap).

Not pasting the whole thing here because of space and all. I will leave the original code and link to the same for reference to the original question/answer.

I'll keep updating this new sample just because ember is fun =)

</Update>

This fiddle shows a static navbar from a view, and the outlet is used only for content display, or you can go directly to the display to see it running

As you can see, you can use a simple view containing your action links and have this view rendered in you application main view. The sub-routes under "starting" also have a mini navbar, coming from a similar template.

Handlebars:

<script type="text/x-handlebars" data-template-name="application">
    <h1>My Ember Application</h1>
    {{view App.NavbarView controllerBinding="controller.controllers.navbarController"}}
    <br /><hr />
    <div class="content">
        {{outlet}}
    </div>
</script>

<script type="text/x-handlebars" data-template-name="navbar">
    <ul>
        <li><a href="#" {{action gotoHome}}>Home</a></li>
        <li><a href="#" {{action gotoStarting}}>Getting Started</a></li>
        <li><a href="#" {{action gotoCommunity}}>Community</a></li>
    </ul>
</script>

<script type="text/x-handlebars" data-template-name="getting-started-menu">
    <ul>
        <li><a href="#" {{action gotoIndex}}>Overview</a></li>
        <li><a href="#" {{action gotoMVC}}>About MVC</a></li>
        <li><a href="#" {{action gotoEmber}}>About Ember</a></li>
    </ul>
</script>
    
<script type="text/x-handlebars" data-template-name="home">
    <h2>Welcome</h2>
    <br />
    <img src="http://emberjs.com/images/about/ember-productivity-sm.png" alt="ember logo" />
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template with no <i>bindings</i>
</script>

<script type="text/x-handlebars" data-template-name="starting">
    <h2>Getting Started with Ember</h2>
    {{view App.StartingMenuView}}
    <br />
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="about-mvc">
    <h2>About MVC</h2>
    {{view App.StartingMenuView}}
    <br /><br />
    <br /><p>
        Model–View–Controller (MVC) is a software design for interactive computer user interfaces that separates the representation of  information from the user's interaction with it.[1][8] The model consists of application data and business rules, and the controller mediates input, converting it to commands for the model or view.[3] A view can be any output representation of data, such as a chart or a diagram. Multiple views of the same data are possible, such as a pie chart for management and a tabular view for accountants.
    </p>
    Read more at <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">Wikipedia</a>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="about-ember">
    <h2>About Ember</h2>
    {{view App.StartingMenuView}}
    <br /><br />
    <br />
    <p>A framework for creating <strong>ambitious</strong> web applications</p>
    Read more at <a href="http://emberjs.com/about/" target="_blank">emberjs.com</a>
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p><br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="community">
    <h1>Ember Community</h1>
    <p>
        Get in touch with the community
    </p>
    <p>Featured contact info:</p>
    {{#each item in content}}
        <a {{bindAttr href="item.linkUrl" }} target="_blank">
            <img height="32" width="32" {{bindAttr src="item.imageUrl" title="item.displayName" alt="item.displayName"}} /><br />
            {{item.displayName}}
        </a><br />
    {{/each}}
    <br />
    Check more information about ember community at <a href="http://emberjs.com/community/" target="_blank">emberjs.com</a>
    <br />
    <br />
    <strong>Note</strong>: This is a template with a <i>foreach</i> type of loop
</script>​

JavaScript:

App = Em.Application.create();

App.ApplicationController = Em.Controller.extend();
App.ApplicationView = Em.View.extend({
    templateName: 'application'
});

App.HomeController = Em.Controller.extend();
App.HomeView = Em.View.extend({
    templateName: 'home'
});

App.NavbarController = Em.Controller.extend();
App.NavbarView = Em.View.extend({
    templateName: 'navbar'
});

App.StartingController = Em.Controller.extend();
App.StartingView = Em.View.extend({
    templateName: 'starting'
});


App.StartingMenuController = Em.Controller.extend();
App.StartingMenuView = Em.View.extend({
    templateName: 'getting-started-menu'
});

App.AboutMVCController = Em.Controller.extend();
App.AboutMVCView = Em.View.extend({
    templateName: 'about-mvc'
});

App.AboutEmberController = Em.Controller.extend();
App.AboutEmberView = Em.View.extend({
    templateName: 'about-ember'
});

App.CommunityModel = Em.Object.extend({
    displayName: null,
    linkUrl: null,
    imageUrl: null
});

App.CommunityController = Em.ArrayController.extend({
    content: [],
    init: function() {
        this._super();
        this.pushObject(
        App.CommunityModel.create({
            displayName: 'Twitter',
            linkUrl: 'https://twitter.com/#!/emberjs',
            imageUrl: 'http://icons.iconarchive.com/icons/iconshots/social-media-network/32/twitter-icon.png'
        }));
        this.pushObject(
        App.CommunityModel.create({
            displayName: 'GitHub',
            linkUrl: 'https://github.com/emberjs/ember.js',
            imageUrl: 'http://www.workinprogress.ca/wp-content/uploads/github.png'
        }));
    }
});

App.CommunityView = Em.View.extend({
    templateName: 'community',
    contentBinding: 'App.CommunityController.content'
});

App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',

    root: Em.Route.extend({
        // EVENTS
        gotoHome: Ember.Route.transitionTo('home'),
        gotoStarting: Ember.Route.transitionTo('starting.index'),
        gotoCommunity: Ember.Route.transitionTo('community.index'),

        // STATES
        home: Em.Route.extend({
            route: '/',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('home');
            }
        }),
        starting: Em.Route.extend({
            // SETUP
            route: '/starting',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('starting');
            },
            // EVENTS
            gotoMVC: Ember.Route.transitionTo('mvc'),
            gotoEmber: Ember.Route.transitionTo('ember'),
            gotoIndex: Ember.Route.transitionTo('index'),

            // STATES
            index: Em.Route.extend({
                route: '/',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('starting');
                }
            }),
            mvc: Em.Route.extend({
                route: '/mvc',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('aboutMVC');
                }
            }),
            ember: Em.Route.extend({
                route: '/ember',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('aboutEmber');
                }
            })
        }),
        community: Em.Route.extend({
            // SETUP
            route: '/community',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('community');
            },
            // EVENTS
            // STATES
            index: Em.Route.extend({
                route: '/',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('community');
                }
            })
        })
    })
});
App.initialize();​

这篇关于使用 Ember 进行导航的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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