emberjs – как пометить активный элемент меню с помощью инфраструктуры маршрутизатора

Я пытаюсь создать навигационные вкладки (взятые из Twitter Bootstrap ):

 

Активная вкладка отмечена class="active" .

Существует отличный пример статической навигации и функции Router / Outlet по адресу http://jsfiddle.net/schawaska/pfbva/ , но я не могу понять, как создать динамическое представление навигации / меню / вкладки.

Насколько я понимаю, в каждом пункте меню можно использовать привязки classов:

  classNameBindings: ['isActive:active'] 

Но где подходящее место для переключения атрибутов isActive?

Если вы используете Ember> = 1.11, то https://stackoverflow.com/a/14501021/65542 ниже – правильный ответ.


Я бы создал NavigationView меню , см. http://jsfiddle.net/pangratz666/z8ssG/ :

Рулевые рейки :

  

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

И внутри connectOutlets вашего маршрута вы должны установить текущий элемент навигации через router.set('navigationController.selected', 'home');


Также рассмотрите repository ember-bootstrap , который обертывает эту и другие функции Bootstrap внутри Ember.js

Ember 1.11+:

 {{#link-to "dashboard" tagName="li"}} Dashboard {{/link-to}} 

Ember <1.11 (требуется bind-attr ):

 {{#link-to "dashboard" tagName="li"}} Dashboard {{/link-to}} 

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

 {{#link-to 'dashboard' tagName='li'}} {{#link-to 'dashboard'}}Link Title{{/link-to}} {{/link-to}} 
  1. link-to с тегом li tagName применяет активный class к li
  2. Внутренний link-to будет элементом anchor который дает вам функцию Open in New Tab при нажатии правой кнопкой мыши

В последнее время появилась возможность использовать Ember-cli addon. Он называется оболочкой ember-cli-active-link-wrapper .

Установите: ember install ember-cli-active-link-wrapper

Вы можете использовать его следующим образом:

 {{#active-link}} {{link-to "Index" "index"}} {{/active-link}} 

что приводит к:

 
  • Index
  • Я знаю, что это старый пост, но вот обновления для Ember 2.4.0

    Для создания ссылок вы можете написать

     {{#link-to 'photoGallery'}} Great Hamster Photos {{/link-to}} 

    или

     {{link-to 'Great Hamster Photos' 'photoGallery'}} 

    Ember автоматически активирует class, когда текущий маршрут совпадает с маршрутом ссылки (в этом примере – photoGallery ).

    Если вы хотите также контролировать «активный» class на других маршрутах, вы можете сделать это, установив атрибут current-when .

     {{#link-to 'photoGallery' current-when='photoGallery photoPreview'}} Great Hamster Photos {{/link-to}} 

    Эта ссылка будет иметь active class как на photoGallery и на маршрутах photoPreview .

    https://github.com/emberjs/ember.js/blob/v2.4.0/packages/ember-routing-views/lib/components/link-to.js#L140

    Рули

      

    Javascript

     App.Router.map(function() { this.route("about"); }); 

    Он автоматически добавит активный class по маршруту. Примечание. Он тестируется с использованием ember-1.0.0-pre.4.js

    Вы также можете изменить метод isActive примерно так:

     isActive: function() { return App.getPath('router.currentState.path') === "root.firms"; }.property("App.router.currentState"), 

    или

     isActive: function() { return this.get('controller.target.currentState.path') === "root.firms"; }.property("controller.target.currentState"), 

    Я вижу, что этот вопрос довольно старый, но если вы обновили Ember.js до RC3, вы можете использовать свойство tagName , например:

     {{#link-to messages tagName="li"}}Messages{{/link-to}} 

    Вот API – http://emberjs.com/api/classes/Ember.LinkView.html

    Не уверен, что это очень динамично, но попытайтесь увидеть решение по адресу http://codebrief.com/2012/07/anatomy-of-an-ember-dot-js-app-part-i-redux-routing-and-outlets/ Основная идея – проверить состояние вашего приложения.

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

    Рули:

     
  • Обновление: решение pangratz выглядит красивее

    Вот полное рабочее решение:

    Посмотреть:

     App.NavView = Ember.View.extend({ tagName: 'li', classNameBindings: ['active'], active: function() { return this.get('childViews.firstObject.active'); }.property() }); 

    Шаблон:

     
      {{#each item in controller}} {{#view App.NavView}} {{#linkTo "item" item tagName="li"}} {{ item.name }} {{/linkTo}} {{/view}} {{/each}}

    Рано или поздно захотите изменить название ваших состояний или что-то еще, что вам нужно пройти через код И представление, а также добавить функцию перехода к каждому маршруту, что нежелательно. Мой подход немного более программный и модульный:

     # 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)

      

    Таким образом, я могу просто создать и объединиться с моими маршрутами в Маршрутизаторе и сохранить Nav-Definitions бок о бок:

     # 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' ) ] ) 

    Ответ baijum выше в основном правилен, однако в последних версиях Ember «bind-attr» устарел. Вот новый способ написать:

     {{#link-to "dashboard" tagName="li"}} Dashboard {{/link-to}} 

    Как вы можете видеть, это еще проще и вроде таких работ, как магия.

    Начиная с v0.8.0 ember-bootstrap поддерживает navs, включая правильное управление активным состоянием. И это без каких-либо ссылок на / 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}} 

    См. http://kaliber5.github.io/ember-bootstrap/api/classes/Components.Nav.html.

    Многие предлагаемые решения здесь не работают ни для какой новой версии Ember (например, устаревшие представления). Более того, использование метода link-to helper не решит проблему, так как bootstrap ожидает, что active class будет присутствовать на

  • не !

    Поэтому я попытаюсь обобщить решения, которые действительно работают на данный момент:

    использовать ember-cli-active-link-wrapper

    Аддон предоставляет компонент для этого специального использования:

      

    Взято с https://stackoverflow.com/a/29939821/5556104

    использовать ember-bootstrap

    ember-bootstrap предоставляет множество компонентов, которые объединяют функциональные возможности бутстрапа в ваше приложение ember, среди которых навигационные компоненты:

     {{#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}} 

    Взято из https://stackoverflow.com/a/38279975/5556104

    ссылка на Hack

    Немного взломанный, но должен работать без дополнительного аддона:

      

    Взято из https://stackoverflow.com/a/23966652/5556104

    Как и другие люди, используя {{#link-to}} для связи с существующим route , когда этот маршрут является текущим URL-адресом, {{#link-to}} будет автоматически добавлять свои classы CSS.

    См. Вопрос о выпуске 4387

  • Схема CRUD, переопределяющая в sails.js
  • Полный пример
  • Обработка ошибок с помощью адаптера (теперь по умолчанию) Ember Data JSON-API
  • Разделить сервер и клиент API REST JSON?
  • Interesting Posts

    Ссылка на объект требуется для нестатического поля, метода или свойства

    Как я могу получить Eclipse для отображения. * Файлов?

    Возможно ли, чтобы ПК одновременно использовал два сетевых соединения?

    Как испустить сигнал кросс-нитки в Qt?

    Где найти исходный код Windows Modern UI?

    Отрегулируйте компоновку, когда включена мягкая клавиатура

    Как встроить манифест приложения в приложение с помощью VS2008?

    Что такое objc_setAssociatedObject () и в каких случаях его следует использовать?

    std :: next_permutation Объяснение реализации

    Как измерить сходство между двумя изображениями?

    Почему компилятор c # испускает Activator.CreateInstance при вызове new in с общим типом с новым () ограничением?

    jQuery и TinyMCE: значение textarea не отправляет

    Что такое спецификатор формата printf для bool?

    Угловой 2 пользовательских ввода формы

    Изменение размера изображения с билинейной интерполяцией без увеличения

    Давайте будем гением компьютера.