【发布时间】:2012-07-04 08:05:25
【问题描述】:
导航侧边栏的“正确方式”(或者至少是选项,如果没有单一的“Ember 方式”)是什么?我应该以某种方式查看 ContainerViews,还是应该只使用新的 outlet 功能并将导航粘贴在我的应用程序视图中?
此外,根据 URL(我正在使用路由)在 li 上设置 .active 类的“正确方法”是什么?有什么帮手吗?
【问题讨论】:
标签: ember.js ember-old-router ember-router
导航侧边栏的“正确方式”(或者至少是选项,如果没有单一的“Ember 方式”)是什么?我应该以某种方式查看 ContainerViews,还是应该只使用新的 outlet 功能并将导航粘贴在我的应用程序视图中?
此外,根据 URL(我正在使用路由)在 li 上设置 .active 类的“正确方法”是什么?有什么帮手吗?
【问题讨论】:
标签: ember.js ember-old-router ember-router
由于最近路由器 API 发生变化,前面的示例不再有效,因此我不会修复这些问题。所有使用旧路由器的应用程序都应尽快迁移到最新版本。
这是一个更新的小提琴: Source | Live Demo
我会经常维护/修复/添加功能。
2013 年 4 月 3 日编辑:
2012 年 11 月 9 日
只是将链接添加到更好的样本,该样本也在选中定向路由时在当前导航栏项中设置op在当前纳维栏项中设置类的一部分
如果您查看 NavigationController,您会看到“selected”属性,我用它来检查子视图 NavigationItemView 的 isActive 方法。 isActive 将根据同一视图(在模板中定义)的menu 属性中的值和(控制器的)属性selected 中的值返回真或假。然后检查 classNameBinding 表达式,该表达式将“活动”设置为该特定孩子的类或不设置任何内容。
还要检查我将导航项标记为选中的 ConnectOutlets。
这是在ember-latest 上运行的。 我还使用了一些 Ember.Bootstrap 以及一些原始的 Twitter Bootstrap 功能/类/等(但我已将样式替换为 metro-bootstrap)。
由于空间和所有的原因,这里没有粘贴整个内容。我将保留原始代码和链接以供参考原始问题/答案。
我会继续更新这个新示例,因为 ember 很有趣 =)
更新>
This fiddle 从视图中显示静态导航栏,outlet 仅用于内容显示,也可以直接进入显示到see it running
如您所见,您可以使用包含您的操作链接的简单视图,并在您的应用程序主视图中呈现此视图。 “开始”下的子路线也有一个迷你导航栏,来自类似的模板。
车把:
<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();
【讨论】:
我不喜欢 MilkyWayJoe 的回答,因为如果您迟早要更改状态的命名或您必须通过代码和视图进行的任何操作,那么还为每条路线添加一个函数似乎是不可取的. 我的方法更加程序化和模块化:
# Parent View-Tamplate, holding the navbar DOM elements
App.NavView = Ember.View.extend(
controller: App.NavArrayController
templateName: "ember-nav"
)
# We push NavItems into this array
App.NavArrayController = Ember.ArrayController.create(
content: Ember.A([])
)
# NavItem has two settable properties and
# an programmatic active state depending on the router
App.NavItem = Ember.Object.extend(
title: ''
goto: null # <=this is the name of the state we want to go to!
active: (->
if App.router.currentState.name == @.get "goto"
true
else
false
).property('App.router.currentState.name').cacheable()
)
# the actual NavElement which gets the class="active" if the
# property "active" is true, plus a on-click binding to
# make the Router transition to this state
App.NavItemView = Ember.View.extend(
tagName: "li"
classNameBindings: ["active"]
click: ->
App.router.transitionTo(@get('goto'))
false
)
nav-view.hbs(用于 twitter-bootstrap 风格的导航)
<div class="nav-collapse collapse">
<ul class="nav">
{{#each App.NavArrayController}}
{{#view App.NavItemView classBinding="active" gotoBinding="goto"}}
<a href="#" {{bindAttr data-goto="goto"}}> {{title}}</a>
{{/view}}
{{/each}}
</ul>
</div>
这样,我可以在路由器中创建和处理我的路由, 并排保持导航定义:
# put this somewhere close to the Router
App.NavArrayController.pushObjects(
[
App.NavItem.create(
title: 'Home'
goto: 'home'
),
App.NavItem.create(
title: 'Chat'
goto: 'chat'
),
App.NavItem.create(
title: 'Test'
goto: 'test'
)
]
)
【讨论】:
a href="#" 设置为href="/#/{{unbound goto}}"时