Как перетаскивать несколько компонентов Angular2 с помощью ng2-dragula

У меня есть компонент Angular2, использующий ng2-dragula для перетаскивания следующим образом:

@Component({
  selector: 'my-comp',
  directives: [
    Dragula
  ],
  viewProviders: [
    DragulaService
  ],
  template: `
    <div class="my-div">
      <div *ngFor="#item of items" [dragula]='"card-bag"' [dragulaModel]='items'>
      ...
      </div>
    </div>
  `
})

Моя проблема: если я создаю несколько компонентов «my-comp», элемент внутри «card-bag» не может перетаскиваться через эти компоненты, хотя у них одинаковое имя пакета. Эти элементы можно перетаскивать только внутри принадлежащего ему компонента.

Есть ли у нас какие-либо конфиги для перетаскивания между компонентами, или это ограничение ng2-dragula?

Спасибо.


person qnreck    schedule 14.03.2016    source источник
comment
Надеюсь, кто-то еще может присоединиться, но я думаю, вам придется сделать это глобальной службой в бутстрапе, чтобы получить такую ​​функциональность. Проблема в том, что когда вы импортируете это в каждый компонент отдельно, он создает новый экземпляр для каждого компонента. Если вы добавите его в свой бутстрап, он станет глобальным приложением для всех ваших компонентов. Я надеюсь, что это отвечает на то, о чем вы спрашивали!   -  person Morgan G    schedule 14.03.2016
comment
@MorganG: спасибо. Я тоже думаю об этой идее, но надеюсь, что у нас будет официальное или лучшее решение этой проблемы.   -  person qnreck    schedule 14.03.2016
comment
Один из способов обойти это: у меня есть служба, представляющая собой глобальную переменную со списком наблюдаемых, и я просто ссылаюсь на эту наблюдаемую или объект каждый раз, когда она мне нужна в других частях моего приложения. Всякий раз, когда мне нужен другой глобальный наблюдаемый объект или объект, я просто добавляю его в этот сервис. Но я согласен, что это кажется немного обратным, чтобы делать все таким образом.   -  person Morgan G    schedule 14.03.2016
comment
@MorganG, можете ли вы рассказать об этом немного кода? Я пытаюсь сделать то же самое, но не могу понять, как получить его глобально.   -  person henk    schedule 24.03.2016
comment
@MorganG, у тебя есть plnkr для этого? у меня есть эта проблема, за исключением того, что у меня есть миниатюры компонентов, и я хочу загружать соответствующие компоненты при перетаскивании миниатюр   -  person Bhushan Gadekar    schedule 28.04.2016
comment
@BhushanGadekar, так что на самом деле мне не приходилось делать много вещей в стиле анимации в Angular2, они заявили, что все еще работают над поиском хороших решений для этого. Это последняя крупная часть, которая выйдет. Вопрос был именно в том, как сделать компонент глобальным компонентом, это тоже ваша проблема?   -  person Morgan G    schedule 28.04.2016
comment
@MorganG Нет, на самом деле у меня есть один глобальный компонент, у которого есть несколько других компонентов в виде директив, т.е. левая боковая панель и компонент макета. Я перечислил миниатюры нескольких своих компонентов на левой боковой панели и хочу перетащить эти миниатюры внутрь компонента макета в качестве компонентов. Но левая боковая панель и макет — это разные компоненты, поэтому я не был уверен, как использовать ng2-dragula, чтобы это произошло? у вас есть рабочий пример для такого сценария?   -  person Bhushan Gadekar    schedule 28.04.2016
comment
@BhushanGadekar, так что я думаю, вам, вероятно, следует спросить об этом в Stack Overflow, но если бы это был я, я бы сделал компонент, обернувший эти два других компонента, и имел бы триггеры перетаскивания, для этого действительно нет хорошего решения из-за того, как компоненты работают в настоящее время . Я бы, конечно, спросил об этом на Stack Overflow, поскольку я не лучший человек, чтобы спрашивать об этом, и кто-то лучше меня, вероятно, уже понял это. Мне жаль, что я не могу помочь больше! Удачи.   -  person Morgan G    schedule 28.04.2016
comment
@MorganG, если ты собираешься спросить об этом где угодно, то сообщи мне об этом ... так что я также смогу это отследить .. респект   -  person Bhushan Gadekar    schedule 28.04.2016
comment
@qnreck вы нашли для этого рабочее решение? Я попытался сделать dragula глобальным, используя метод angular2 UpgradeAdaptor addProvider. Но пока это не работает.   -  person jhulme    schedule 19.05.2016


Ответы (2)


Если вы не используете [dragulaModel], то перетаскивание между вложенными компонентами работает хорошо, если вы устанавливаете viewProviders: [ DragulaService ] только один раз в верхнем/корневом компоненте.

Не забудьте не устанавливать viewProviders: [ DragulaService ] в других компонентах, так как это создает новые экземпляры для каждого компонента.

Изменить: недавно я реализовал данный сценарий, используя пакет ng2-dnd npm. Это лучше, чем ng2-dragula, и предлагает простую передачу объектов и другие вещи. Это может решить вашу проблему.

person Bhushan Gadekar    schedule 24.05.2016
comment
Спасибо за упоминание ng2-dnd, это отличная находка, проста в использовании, отлично работает! - person rmcsharry; 20.12.2016
comment
Спасибо, ng2-dnd потрясает, все мое требование состояло в том, чтобы иметь возможность переносить данные через перетаскиваемые и перетаскиваемые элементы div, ng2-dnd идеально подходит для этого, я бы порекомендовал всем dnd вместо dragula. - person pritesh agrawal; 11.07.2017

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

Компонент верхнего уровня

  • CSS ViewEncapsulation.None, включите сюда любой css
  • Директива Драгулы
  • DragulaService ViewProvider
  • Регистрация фильтра accepts в сервисе dragula, который предотвращает попадание элементов внутрь себя

    accepts: (el: Element, target: Element, source: Element, sibling: Element): boolean => {
     return !el.contains(target); // elements can not be dropped within themselves
    },
    
  • Регистрация фильтра moves в сервисе dragula, чтобы весь элемент перемещался вместе

    moves: (el: Element, container: Element, handle: Element): boolean => {
      // only move favorite items, not the icon element
      return el.tagName.toLowerCase() === 'mvp-navigation-item';
    },
    
  • HTML-шаблон выглядит так

    <div class="nav--favorites__root" [class.is-dragging]="isDragging" [dragula]="'favorites'" [dragulaModel]="favoriteLinks">
      <navigation-item *ngFor="let link of links" [link]="link">
      </navigation-item>
    </div>
    

Компонент элемента навигации

  • Директива Драгулы
  • Нет DragulaService ViewProvider
  • HTML-шаблон выглядит так

    <a href class="list-group-item" linkActive="active" [linkTo]="link?.url" (click)="followLink($event, link)">
      <span class="glyphicon glyphicon-{{link?.icon ? link?.icon : 'unchecked'}}"></span>
      <span class="nav__label">{{link?.label}}</span>
    </a>
    <div *ngIf="link?.children" class="list-group list-group-inverse nav--favorites__submenu" [class.is-expanded]="link?.isExpanded" [class.is-empty]="link?.children?.length === 0" [dragula]="'favorites'" [dragulaModel]="link?.children">
      <navigation-item *ngFor="let childLink of link?.children" [link]="childLink">
      </navigation-item>
      <!-- the nav favorites items must be the first elements in the dragula container or the model sync gets confused -->
      <a class="btn btn-link toggle" (click)="link.isExpanded = !link.isExpanded; $event.preventDefault();"><span class="glyphicon glyphicon-triangle-{{link?.isExpanded ? 'top' : 'bottom'}}"></span></a>
    </div>
    

Вам нужно будет стилизовать вещи, чтобы сделать подменю .nav--favorites__ видимым в качестве цели перетаскивания при перетаскивании элемента.

person Isaac    schedule 16.06.2016
comment
Никакая директива Dragula в дочернем dragula не выдает ошибку, например, «Dragula не является родным свойством». Он не может запустить какой-либо тег с [dragula], так как не указаны никакие директивы. Не уверен, что ваш ответ правильный, я думаю, что нет. - person Becario Senior; 01.09.2016
comment
@BecarioSenior после RC5 директивы объявляются в ngModule вместо отдельных компонентов. Помимо этого изменения, все по-прежнему работает. Убедитесь, что DragulaService объявлен в верхнем компоненте или в ngModule, но не в дочерних компонентах, поскольку нам нужен один общий экземпляр службы. - person Isaac; 01.09.2016
comment
Не знал, спасибо! - person Becario Senior; 03.09.2016
comment
Это работает для меня, но я не могу найти способ перетащить, например, 2 следующих элемента вместе. У меня есть режим выбора, но я понятия не имел, как сохранить его вместе в режиме перетаскивания... - person kris_IV; 16.01.2019