Подтвердить что ты не робот

Назначение "активного" класса выбранному элементу списка в EmberJS

У меня есть список, и я хотел бы установить один элемент как class= "active" автоматически. Учитывая следующий код начальной загрузки:

<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 и atLogin находятся в моем ApplicationController.

Сделать как:

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

Какой лучший способ сделать это с помощью Ember 1.0 pre4? Я бы предпочел не добавлять специальный код ко всем представлениям или контроллеру.

PS - atIndex: true работает, но atIndex: function() {return true; }.property().volatile() нет. Это заставляет меня думать, что я делаю что-то неправильно.

Спасибо!

4b9b3361

Ответ 1

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

Ответ 2

На сегодняшний день самым чистым способом решения этой проблемы является использование встроенной поддержки linkTo для установки активного класса при визуализации ссылок. AFAIK это еще не задокументировано, кроме как в исходном коде:

реализация: https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/helpers/link_to.js#L46

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

Чтобы воспользоваться этой возможностью, просто настройте свой CSS на стиль на основе наличия активного класса в ссылке вместо элемента li. Если вам действительно нужно стилизовать li, вы можете создать пользовательский вид и помощник, который расширяет Ember.LinkView и использует li, но изменение css будет намного проще.

--- ОБНОВЛЕНИЕ ----

Поскольку мы все любим twitter bootstrap, просто изменение css, возможно, не является таким отличным вариантом. В этом случае следующее будет делать трюк:

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')
});

Рабочий пример с использованием ember linkTo помощник с бутстрапными таблетками: http://jsbin.com/ekobod/5/edit (требуется ember-1.0.0-pre.4)

Ответ 3

активный маршрут маршрута автоматически обновляется в ApplicationController через currentPath, поэтому я сделал что-то подобное в своем приложении... В ApplicationController добавлены такие свойства:

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

и в моем шаблоне ApplicationView:

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

Ответ 5

ИЗМЕНИТЬ: Наконец, лучший способ, которым я нашел использование класса активации элемента bootstrap li, используя ember.js ссылки.

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

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

DEPRECATED:

Я думаю, что предыдущие ответы были актуальны, прежде чем Ember.js представила атрибут activeClass для helper linkTo. Теперь я бы решил проблему следующим образом:

<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 автоматически добавит класс, если это необходимо.

Ответ 6

Если я могу предложить другое решение, которое не требует ничего, кроме Handlebars:

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

Это устанавливает объект LinkView как элемент родительского представления, к активному атрибуту которого вы можете обратиться.

Ответ 7

Я нашел довольно простое решение, используя связанные элементы в группе списка (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>

Работает с Bootstrap v3.1.1 и Ember v1.7.0

Ответ 8

Просто вставьте {{link-to}} с именем tag на внешнем. Я делаю это на EmberJS 2.0.

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

Ответ 10

Многие из этих ответов устарели. Вот гораздо более чистая (и DRY) версия для Bootstrap и Ember 2.x:

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

Ответ 11

Я решил аналогичную проблему, создав представление для каждого элемента и используя classNameBindings (я должен сказать, что у меня нет списка HTML, т.е. <a>...</a> в моем приложении, просто список <div>).

Вот как это работает для меня:

В tasklist.handlebars я итерации по моему пользовательскому представлению

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

Ember будет вставлять представление (например, <div>) для каждого элемента.

Класс представления для каждого элемента определяется в task_list_item_view.js как

App.TaskListItemView = Ember.View.extend({

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

  isClosed: function() {
      var content = this.get('content');
      return content && !content.isOpen(new Date);
  }.property('[email protected]'),

  isSelected: function() {
      return (this.get('controller').isSelectedTask(this.get('content')));
  }.property('[email protected]'),

  ....
});

Наконец, шаблон для представления просто отображает мою ссылку в tasklistitem.handlebars

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

AFAIK вы должны указать исходные данные в вызове property(), чтобы ember знал, когда (повторно) оценить свойство.

Надеюсь, что поможет

Ответ 12

Я пошел с:

 Ember.LinkView.reopen({
didInsertElement:function(){

    if(this.$().hasClass('active')){

        this.$().parent().addClass('active');

    }
}

});

Я не хотел использовать принятый ответ, поскольку хотел, чтобы мои элементы li были обычным старым html. Возможно, есть лучший способ проверить активное состояние, но я не смог получить доступ к правильному свойству.