Angularjs: Найти все экземпляры директивы - программирование
Подтвердить что ты не робот

Angularjs: Найти все экземпляры директивы

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

  • Создайте директиву с контроллером, который позволяет другим директивам регистрироваться (и отменить регистрацию на $destroy). Но это будет не по порядку, если я добавлю что-нибудь посередине позже. Кроме того, я пробовал написать его таким образом, и это похоже на то, как больше кода, чем необходимо.

  • Всякий раз, когда пользователь нажимает клавишу со стрелкой, создавайте пустой массив и $broadcast событие, с обратным вызовом для того, чтобы директивы регистрировались в этом списке. Затем, как только этот список будет заполнен, перейдите или перейдите на него назад. Они (должны?) Вернутся в том порядке, в котором они находятся на DOM, но я не уверен, так как этот путь кажется сумасшедшим и хакерским.

  • Отметьте вещи, которые "tabbable" с помощью css, и напишите это простым способом в jquery, примерно так: В новом событии click var all = $('.tabbable'), а затем сделайте очевидное с этим. Но я действительно не хочу так поступать, потому что это не "способ angular". Не из-за какого-то чувства чистоты, а потому, что я строю это как часть большей библиотеки виджетов, и я хочу, чтобы эта функциональность была доступной для них.

Итак, есть ли какой-либо способ для меня получить возможности всех директив определенного типа, не прибегая к странным хакам или распространяя логику повсюду?

4b9b3361

Ответ 1

Это хороший вопрос. +1

Сначала поиск всех директив или узлов по типу идет против пути Angular. The View является официальной записью в AngularJS, поэтому директивы должны сообщать, что они делают, и делать то, что они говорят. Кодирование некоторого процесса где-то для сканирования узлов DOM и действия соответственно проблематично по нескольким причинам, не последним из которых является разделение проблем и проверяемости.

Я рад видеть, что вы смотрите на другие варианты, но я согласен с тем, что другие варианты, которые вы предоставили, не оптимальны по тем причинам, о которых вы упомянули. Но у меня есть еще один. Это тот, который я использовал для другого приложения, но это требовало знания разбросанных узлов DOM.

Сначала мы создаем службу для управления состоянием этого компонента. Это просто. Позвольте называть его SectionsService. Затем мы создаем директиву для регистрации разделов. Позвольте называть это section для простоты. Директива section регистрирует идентификатор DOM node (возможно, созданный программно для обеспечения уникальности) с SectionsService во время фазы связывания. Поскольку DOM обрабатывается (в основном) по порядку, узлы, добавленные в SectionsService, также будут в порядке. Таким образом, DOM выглядит примерно так (несущественные вещи опущены):

<div section>...</div>

<!-- other stuff -->

<div section>...</div>

<!-- other stuff -->

<!-- etc. -->

(Несмотря на то, что здесь отсутствует область действия, было бы непросто запрограммировать его таким образом, чтобы порядок не имел значения, но он был бы основан на специфике вашего приложения, которое я не знаю).

Затем вы создаете триггеры, как обработчик стрелки. В этих случаях вы просто указываете SectionService перейти к предыдущему/следующему node в списке. AngularJS поставляется с сервисом под названием $anchorScroll, который можно использовать для эмуляции позиционирования, основанного на хэш-настройках браузера, с которым мы знакомы. Очевидно, вы также можете использовать плагин jQuery для анимации прокрутки, если хотите.

И это! Очень простая директива, довольно простой сервис и любой триггер (ы), который вам нужен. Все сказанное, я думаю, менее 100 строк кода, включая тесты. Все компоненты развязаны и легко проверяются, но все еще очень просты. Взгляд остается "Истиной". Путь Angular сохраняется.

И было много радости.


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

Ответ 2

Услуги AngularJS являются одноточечными и могут потребоваться через инъекцию зависимости. Вы могли бы потребовать, чтобы ваши директивы требовали службу диспетчера состояний и вызывали приращения/декременты.

Альтернативно, немного проще, но более хрупким, вы можете сохранить массив в $rootScope. Это более идиоматический "angular" (но не намного), чем селектор jQuery глобальный, но, вероятно, не лучший маршрут, если вы создаете библиотеку виджетов.