J'essaie de créer des onglets de navigation (extraits de Twitter Bootstrap ):
<ul class="nav nav-tabs">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Messages</a></li>
</ul>
L'onglet actif est marqué avec class="active"
.
Il existe un excellent exemple de fonction de barre de navigation statique et de routeur/prise à l'adresse http://jsfiddle.net/schawaska/pfbva/ , mais Je ne comprends pas comment créer une vue dynamique de barre de navigation/menu/onglet .
Autant que je sache, il est possible d'utiliser des liaisons de classe dans chaque élément de menu:
classNameBindings: ['isActive:active']
Mais où est le bon endroit pour changer les attributs isActive?
Si vous utilisez Ember> = 1.11, alors https://stackoverflow.com/a/14501021/65542 ci-dessous est la bonne réponse.
Je créerais un NavigationView
, voir http://jsfiddle.net/pangratz666/z8ssG/ :
Guidon:
<script type="text/x-handlebars" data-template-name="navigation">
<ul class="nav nav-tabs">
{{#view view.NavItemView item="home" }}
<a {{action gotoHome}} >Home</a>
{{/view}}
{{#view view.NavItemView item="profiles" }}
<a {{action gotoProfiles}} >Profiles</a>
{{/view}}
{{#view view.NavItemView item="messages" }}
<a {{action gotoMessages}} >Messages</a>
{{/view}}
</ul>
</script>
JavaScript:
App.NavigationView = Em.View.extend({
templateName: 'navigation',
selectedBinding: 'controller.selected',
NavItemView: Ember.View.extend({
tagName: 'li',
classNameBindings: 'isActive:active'.w(),
isActive: function() {
return this.get('item') === this.get('parentView.selected');
}.property('item', 'parentView.selected').cacheable()
})
});
Et à l'intérieur de connectOutlets
de votre route, vous devez définir l'élément de navigation actuel via router.set('navigationController.selected', 'home');
...
Jetez également un coup d'oeil au répertoire ember-bootstrap qui englobe tout cela, ainsi que d'autres fonctionnalités de Bootstrap dans Ember.js
Ember 1.11+:
{{#link-to "dashboard" tagName="li"}}
<a href="{{view.href}}">Dashboard</a>
{{/link-to}}
Ember <1.11 (bind-attr
requis):
{{#link-to "dashboard" tagName="li"}}
<a {{bind-attr href="view.href"}}>Dashboard</a>
{{/link-to}}
Certaines des suggestions ci-dessus sont toujours valables pour le cas de démarrage de Twitter. Vous pouvez aussi essayer quelque chose comme ça
{{#link-to 'dashboard' tagName='li'}}
{{#link-to 'dashboard'}}Link Title{{/link-to}}
{{/link-to}}
link-to
avec li
tagName applique la classe active au lilink-to
interne serait un élément anchor
qui vous donne la fonctionnalité Open in New Tab
lorsque vous cliquez avec le bouton droit de la sourisUn addon Ember-cli est récemment disponible. Il s'appelle ember-cli-active-link-wrapper .
Installer: ember install ember-cli-active-link-wrapper
Vous pouvez l'utiliser comme ceci:
{{#active-link}}
{{link-to "Index" "index"}}
{{/active-link}}
qui se traduit par:
<li class='active'>
<a href="/" class='active'>Index</a>
</li>
Je sais que c’est un vieux message, mais voici des mises à jour pour Ember 2.4.0
Pour créer des liens, vous pouvez écrire
{{#link-to 'photoGallery'}}
Great Hamster Photos
{{/link-to}}
ou
{{link-to 'Great Hamster Photos' 'photoGallery'}}
Ember définira automatiquement la classe sur active lorsque la route actuelle correspond à la route de link (dans cet exemple photoGallery
).
Si vous souhaitez également contrôler la classe 'active' sur d'autres routes, vous pouvez le faire en définissant l'attribut current-when
.
{{#link-to 'photoGallery' current-when='photoGallery photoPreview'}}
Great Hamster Photos
{{/link-to}}
Ce lien aura la classe active
sur les routes photoGallery
et photoPreview
.
Guidon
<ul class="nav">
<li>{{#linkTo "index"}}Index{{/linkTo}}</li>
<li>{{#linkTo "about"}}About{{/linkTo}}</li>
</ul>
Javascript
App.Router.map(function() {
this.route("about");
});
Il ajoutera automatiquement une classe active en fonction de la route .
Je vois que cette question est assez ancienne, mais si vous mettez à niveau Ember.js vers le RC3, vous pouvez utiliser la propriété tagName
, comme:
{{#link-to messages tagName="li"}}Messages{{/link-to}}
Voici l'API - http://emberjs.com/api/classes/Ember.LinkView.html
Vous pouvez également changer la méthode isActive en quelque chose comme ceci:
isActive: function() {
return App.getPath('router.currentState.path') === "root.firms";
}.property("App.router.currentState"),
ou
isActive: function() {
return this.get('controller.target.currentState.path') === "root.firms";
}.property("controller.target.currentState"),
Pas sûr que ce soit très dynamique, mais essayez de voir la solution sur http://codebrief.com/2012/07/anatomy-of-an-ember-dot-js-app-part-i-redux-routing-and- points de vente/ L'idée principale est de vérifier l'état de votre application
JavaScript:
function stateFlag(name) {
return Ember.computed(function() {
var state = App.router.currentState;
while(state) {
if(state.name === name) return true;
state = state.get('parentState');
}
return false;
}).property('App.router.currentState');
}
ApplicationController: Ember.Controller.extend({
isHome: stateFlag('home'),
isSections: stateFlag('sections'),
isItems: stateFlag('items')
})
Guidon:
<li class="home" {{bindAttr class="isHome:active"}}>
</li>
<li class="sections" {{bindAttr class="isSections:active"}}>
</li>
<li class="items" {{bindAttr class="isItems:active"}}>
</li>
Mise à jour: la solution de Pangratz est plus jolie
Voici une solution de travail complète:
Vue:
App.NavView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['active'],
active: function() {
return this.get('childViews.firstObject.active');
}.property()
});
Modèle:
<ul>
{{#each item in controller}}
{{#view App.NavView}}
{{#linkTo "item" item tagName="li"}}
<a {{bindAttr href="view.href"}}>
{{ item.name }}
</a>
{{/linkTo}}
{{/view}}
{{/each}}
</ul>
À partir de la version 0.8.0 ember-bootstrap , prend en charge les navs, y compris la gestion correcte de l'état actif. Et cela sans aucun type de hacks link-to/tagName:
{{#bs-nav type="pills"}}
{{#bs-nav-item}}
{{#link-to "foo"}}Foo{{/link-to}}
{{/bs-nav-item}}
{{#bs-nav-item}}
{{#link-to "bar"}}Bar{{/link-to}}
{{/bs-nav-item}}
{{/bs-nav}}
Voir http://kaliber5.github.io/ember-bootstrap/api/classes/Components.Nav.html
Un grand nombre des solutions proposées ici ne fonctionnent avec aucune version récente d'Ember (les vues étant par exemple obsolètes). De plus, le simple fait d'utiliser l'assistant link-to
ne résoudra pas le problème, car bootstrap s'attend à ce que la classe active
soit présente sur le <li>
et non le <a>
!
Je vais donc essayer de résumer les solutions qui fonctionnent réellement à partir de maintenant:
L'addon fournit un composant pour ce cas d'utilisation spécial:
<ul class="nav nav-tabs">
{{#active-link}}
{{#link-to "foo"}}Foo{{/link-to}}
{{/active-link}}
{{#active-link}}
{{#link-to "bar"}}Bar{{/link-to}}
{{/active-link}}
</ul>
Extrait de https://stackoverflow.com/a/29939821/5556104
ember-bootstrap fournit de nombreux composants qui intègrent la fonctionnalité d'amorçage dans votre application ember, parmi lesquels les composants de navigation:
{{#bs-nav type="tabs"}}
{{#bs-nav-item}}
{{#link-to "foo"}}Foo{{/link-to}}
{{/bs-nav-item}}
{{#bs-nav-item}}
{{#link-to "bar"}}Bar{{/link-to}}
{{/bs-nav-item}}
{{/bs-nav}}
Tiré de https://stackoverflow.com/a/38279975/5556104
Un peu hacky, mais devrait fonctionner sans aucun addon supplémentaire:
<ul class="nav nav-tabs">
{{#link-to "foo" tagName="li"}}
{{#link-to "foo"}}Foo{{/link-to}}
{{/link-to}}
{{#link-to "bar" tagName="li"}}
{{#link-to "bar"}}Bar{{/link-to}}
{{/link-to}}
</ul>
Extrait de https://stackoverflow.com/a/23966652/5556104
Comme d'autres personnes l'ont dit, en utilisant {{#link-to}}
pour créer un lien vers une route
existante, lorsque cette route est une URL actuelle, {{#link-to}}
ajoutera automatiquement active
à ses classes CSS.
Voir Ember numéro 4387
la réponse de baijum ci-dessus est généralement correcte, mais dans les dernières versions d'Ember, le "bind-attr" est obsolète. Voici la nouvelle façon de l'écrire:
{{#link-to "dashboard" tagName="li"}}
<a href="{{view.href}}">Dashboard</a>
{{/link-to}}
Comme vous pouvez le constater, c’est encore plus simple et fonctionne comme par magie.
Tôt ou tard, vous voulez changer le nom de vos états ou quoi que ce soit que vous ayez à parcourir le code ET la vue, ajouter une fonction à la transition Pour chaque route ne semble pas souhaitable. Mon approche est un peu plus programmatique et modularisée:
# 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 (pour les navigateurs de style 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>
Ainsi, je peux créer et modifier mes itinéraires dans le routeur, .__ et conserver les définitions de navigation côte à côte:
# 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'
)
]
)