Контроллеры доступа к нескольким идентичным директивам, использующим одну родительскую область

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

<body>
  <xx-button xx-draggable>
  <xx-button xx-draggable>
<body>

См. этот jsfiddle для реализации.

Полученный DOM:

<xx-button class="ng-isolate-scope ng-scope" draggable="true" hm-panstart="$draggableCtrl.ondragstart($event)" hm-panend="$draggableCtrl.ondragend($event)" hm-panmove="$draggableCtrl.ondrag($event)" style="-moz-user-select: none;">
  <button class="btn ng-binding" ng-click="$ctrl.onclick()">
    CLICK ME
  </button>
</xx-button>

Директива xx-draggable изменит dom директивы xx-button, чтобы добавить пару обработчиков молотка (я использую angular-hammer) для управления перетаскиванием кнопки. xx-draggableДиректива имеет свой собственный контроллер, который использует controllerAsявное имя it ($draggableCtrl). Как я понимаю, controllerAsбудет в основном прикрепить контроллер к области, так что в шаблоне вы можете обратиться к нему. Проблема, в моем случае, кажется controllerAs присоединяет оба контроллера к одной и той же области, в результате чего только контроллер директивы, примененной на второй кнопке, будет доступен. Поэтому, когда я перетаскиваю первую кнопку (button1), вторая кнопка (button2) эффективно перетаскивается…

Мое понимание заключается в том, что компонент должен иметь изолированную область, поэтому оба не должны вмешиваться. Вторая controllerAsдиректива должна быть прикреплена $draggableCtrlк области действия второй кнопки и не должно быть никакого перекрытия.

Есть идеи, что происходит ?

Обновить:

Я считаю, что основная причина моей проблемы описана здесь:

В общем случае можно применить несколько директив к одной
элемент, но могут быть ограничения в зависимости от типа области
требуется директивами. Следующие пункты помогут объяснить
это ограничение. Для простоты принимаются только две директивы
учетная запись, но она также применима для нескольких директив:

[…]

изолированная область + Нет области => изолированная директива будет использовать свой собственный
создана изолированная область. Другая директива будет использовать родительскую директиву
масштаб

Таким образом, xx-draggable связан не с xx-button scope, а с его родительской областью, поэтому контроллер перезаписывается. На мой взгляд, это противоречит интуиции.

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

1 ответ

  1. В конце концов, я остановился на далеко не идеальном решении, но которое на самом деле работает относительно «безопасным» способом, без предположений о том, как оно используется.

    Для того, чтобы иметь возможность ссылаться на контроллеры моей директивы независимо в шаблоне, я создаю искусственный «subScope». В функции link я создаю случайно именованный элемент области:

    const subScope = '_' + Math.random() * 100000000000000000;
    

    Я назначаю контроллер этому случайно сгенерированному элементу:

    scope[subScope] = ctrl;
    

    Затем, когда я изменяю DOM для присоединения обработчиков, я использую эту случайную ссылку:

    attr.$set('hm-panstart', subScope + '.ondragstart($event)');
    attr.$set('hm-panend', subScope + '.ondragend($event)');
    attr.$set('hm-panmove', subScope + '.ondrag($event)');
    

    См. это jsfiddle для рабочего решения.