web-dev-qa-db-fra.com

Assigner la classe 'active' à l'élément de liste sélectionné dans EmberJS

J'ai une liste et j'aimerais définir un élément comme étant class = "actif" automatiquement. Étant donné le code d'amorçage suivant:

<ul class="nav">
<li {{bindAttr class="atIndex:active"}}>{{#linkTo "index"}}Index{{/linkTo}}</li>
<li {{bindAttr class="atAbout:active"}}>{{#linkTo "about"}}About{{/linkTo}}</li>
<li {{bindAttr class="atLogin:active"}}>{{#linkTo "login"}}Login{{/linkTo}}</li>
</ul>

atIndex, atAbout et atLogin résident dans mon ApplicationController.

Rendre en tant que:

<ul class="nav">
<li class="active"><a...>Index{{/linkTo}}</li>
<li><a...>About<a></li>
<li><a...>Login<a></li>
</ul>

Quelle est la meilleure façon de faire cela avec Ember 1.0 pre4? Je préfère ne pas ajouter de code spécial à chaque vue ou contrôleur.

PS - atIndex: true fonctionne, mais pas atIndex: function() {return true; }.property().volatile(). Ce qui me fait penser que je fais quelque chose de mal.

Je vous remercie!

40
shs
{{#link-to "dashboard" tagName="li" href=false}}
  <a {{bind-attr href="view.href"}}>
    Dashboard
  </a>
{{/link-to}}
75
lesyk

Le moyen le plus simple de résoudre ce problème consiste à tirer parti du support intégré de l'assistant linkTo pour la définition de la classe active lors du rendu des liens. Autant que je sache, cela n’est pas encore documenté autrement que dans le code source:

implementation: https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/helpers/link_to.js#L46

exemple: https://github.com/emberjs/ember.js/blob/master/packages/ember/tests/helpers/link_to_test.js#L120

Pour tirer parti de cette fonctionnalité, il vous suffit d’ajuster votre style CSS sur la base d’une classe active sur le lien au lieu de l’élément li. Si vous avez vraiment besoin de nommer la li, vous pouvez créer une vue personnalisée et un assistant qui étend Ember.LinkView et utilise une li, mais la modification du fichier css sera beaucoup plus facile.

--- METTRE À JOUR ----

Puisque nous aimons tous Twitter, le bootstrap changer le fichier CSS n’est peut-être pas une si bonne option. Dans ce cas, ce qui suit fera l'affaire:

App.ApplicationView = Ember.View.extend({
  currentPathDidChange: function() {
    Ember.run.next( this, function() {
      this.$("ul.nav li:has(>a.active)").addClass('active');
      this.$("ul.nav li:not(:has(>a.active))").removeClass('active');
    });
  }.observes('controller.currentPath')
});

Exemple de travail utilisant ember linkTo helper avec des pilules bootstrap: http://jsbin.com/ekobod/5/edit (requiert ember-1.0.0-pre.4)

14
Mike Grassotti

J'ai créé un addon ember-cli qui gère ceci:

https://github.com/alexspeller/ember-cli-active-link-wrapper

5
alexspeller

le chemin de la route active est mis à jour automatiquement dans le ApplicationController via currentPath alors j'ai fait quelque chose comme ça dans mon application ... Dans ApplicationController, des propriétés ont été ajoutées de la manière suivante:

isProductsActive: function(){
  if ( this.get('currentPath') === 'products' ) return 'active';
  else return '';
}.property('currentPath')

et dans mon modèle ApplicationView:

<li {{bindAttr class="isProductsActive"}}>
  {{#linkTo "products"}}Products{{/linkTo}}
</li>
5
colymba

EDIT: Enfin, le meilleur moyen que j’ai trouvé d’utiliser la classe activate de l’élément bootstrap li en utilisant ember.js du lien.

{{#linkTo "dives" tagName="li"}}
   <a {{bindAttr href="view.href"}}>Dives</a>
{{/linkTo}}

-------------- 8 <--------------

PÉRIMÉ:

Je suppose que les réponses précédentes étaient pertinentes avant qu'Ember.js n'introduise l'attribut activeClass de linkTo helper . Je résoudrais maintenant le problème de la manière suivante:

<ul class="nav">
<li >{{#linkTo "index" activeClass="active"}}Index{{/linkTo}}</li>
<li >{{#linkTo "about" activeClass="active}}About{{/linkTo}}</li>
<li >{{#linkTo "login" activeClass="active}}Login{{/linkTo}}</li>
</ul>

Enber ajoutera automatiquement la classe si nécessaire.

3
Cyril

J'ai trouvé une solution simple en utilisant des éléments liés dans un groupe de listes ( http://getbootstrap.com/components/#list-group-linked ). 

<div class="list-group">
{{#each thing in list}}
    {{#link-to "details" thing.id tagName="a" href="view.href" class="list-group-item" {{thing.name}} {{/link-to}}
{{/each}}
</div>

Fonctionne avec Bootstrap v3.1.1 et Ember v1.7.0

2
Karda

Il suffit d'imbriquer le {{link-to}} avec un tagName sur celui qui est à l'extérieur. Je le fais sur EmberJS 2.0.

{{#link-to "admin.websocket" tagName="li"}}
    {{#link-to "admin.websocket"}}WebSocket{{/link-to}}
{{/link-to}}
2
Chris Carey

Si je peux suggérer une autre solution qui ne nécessite que des poignées:

<li {{bind-attr class="view.innerLink.active:active"}}>
    {{#link-to "path" viewName="innerLink"}}Click{{/link-to}}
</li>

Cela définit l'objet LinkView en tant que membre de la vue parent, attribut actif que vous pouvez ensuite référencer.

2
Elte Hupkes

Beaucoup de ces réponses sont obsolètes. Voici une version beaucoup plus propre (et sèche) pour Bootstrap et Ember 2.x:

{{#link-to "index" tagName="li" as |link|}}
  <a href="#" class="{{if link.active 'active'}}">Index Page</a>
{{/link-to}}
1
Sukima

Si vous souhaitez utiliser la navigation Bootstrap dans Ember, vous pouvez utiliser Bootstrap pour Ember qui offre une prise en charge immédiate:

Github: https://github.com/ember-addons/bootstrap-for-ember Démo: http://ember-addons.github.io/bootstrap-for-ember/dist/ #/show_components/tabs

1
asaf000

J'ai résolu un problème similaire en créant une vue pour chaque élément et en utilisant classNameBindings (je dois dire que je n'ai pas de liste HTML, c'est-à-dire .<a>...</a> dans mon application, mais une liste de <div>).

Voici comment cela fonctionne pour moi:

Dans tasklist.handlebars, je parcours ma vue personnalisée.

  {{#each tasks}}
    {{view App.TaskListItemView contentBinding="this"....}}
  {{/each}}

Ember insérera une vue (par ex. <div>) pour chaque élément.

La classe de vue pour chaque élément est définie dans task_list_item_view.js en tant que

App.TaskListItemView = Ember.View.extend({

  controller: null,
  classNameBindings: ['isSelected', 'isClosed'],

  isClosed: function() {
      var content = this.get('content');
      return content && !content.isOpen(new Date);
  }.property('controller.content.@each'),

  isSelected: function() {
      return (this.get('controller').isSelectedTask(this.get('content')));
  }.property('controller.taskSelection.@each'),

  ....
});

Enfin, le modèle pour la vue rend mon lien dans tasklistitem.handlebars

<a {{action "selectTask" view.content target="view"}} rel="tooltip"
         {{bindAttr title="view.content.comment"}} class="taskListLink">
  ....
</a>

Autant que je sache, vous devez spécifier les données source dans l'appel property() pour que le membre sache quand (ré) évaluer la propriété.

J'espère que cela pourra aider

0
Thomas Herrmann