Как назначить угловую директиву элементу html, используя ElementRef и Renderer2? - PullRequest
0 голосов
/ 08 сентября 2018

Я занимаюсь разработкой приложения перетаскивания в Angular 6 и операции перетаскивания, я создаю новый элемент HTML (элементы, такие как 'DIV', 'textarea' и т. Д.), Динамически и назначаю стили, атрибуты, значения по умолчанию x и y координирует его, используя функции приложения ElementRef и Renderer2 и добавляя вновь созданный HTML-элемент к родительскому элементу, над которым выполняется операция удаления.

У меня также есть угловая директива, которая придает перетаскиваемое поведение недавно созданному элементу HTML, чтобы пользователь мог переместить его в любом месте родительского элемента. Частичный код для директивы приведен ниже:

@Directive({
  selector: '[appMovable]'
})
export class MovableDirective {

  @HostBinding('style.transform') get transform(): SafeStyle {
    return this.sanitizer.bypassSecurityTrustStyle(
      `translateX(${this.position.x}px) translateY(${this.position.y}px)`);
  }
  private position = {x: 100, y: 0};

  constructor(private sanitizer: DomSanitizer) {
  }

  @HostListener('dragStart') onDragStart() {
    console.log('drag start');
    // Code to calculate the start position of the control being dragged....
  }

  @HostListener('dragMove') onDragMove() {
    console.log('drag move');
    // Code to calculate the current position of the control while it is being dragged....
  }

  @HostListener('dragEnd') onDragEnd() {
    console.log('drag end');
    // Code to calculate the end position of the control being dragged and the the position of the control properly.....
  }
}

Хотя я могу назначить стили, атрибуты и координаты x и y по умолчанию для только что созданного элемента, но я не могу связать директиву appMovable с вновь созданным элементом HTML. Код для создания элемента HTML и присвоения ему различных атрибутов приведен ниже:

@Directive({
  selector: '[appDroppable]'
})
export class DroppableDirective {

  constructor(private elementRef: ElementRef, private renderer: Renderer2) { 
}

  @HostListener('dragover', ['$event'])
  public onDragOver(evt) {
    evt.preventDefault();
    evt.stopPropagation();
  }

  @HostListener('dragleave', ['$event'])
  public onDragLeave(evt) {
    evt.preventDefault();
    evt.stopPropagation();
  }

  @HostListener('drop', ['$event'])
  public onDrop(evt) {
    evt.preventDefault();
    evt.stopPropagation();

    // Since text element is being dragged so create new textarea html control
    const textareaElement = this.renderer.createElement('textarea');
    this.renderer.setAttribute(textareaElement, 'placeholder', 'click to add content...');
    this.renderer.setAttribute(textareaElement, 'class', 'proInput editing');
    this.renderer.setAttribute(textareaElement, 'draggable', 'true');

    //Assign the appMovable directive to element
    this.renderer.setAttribute(textareaElement, 'appMovable', '');

    // this.renderer.appendChild(newDivElement, textareaElement);
    this.renderer.appendChild(this.elementRef.nativeElement, textareaElement);
  }
}

Когда я проверяю вновь созданный элемент HTML в инструменте отладчика браузера, я вижу, как директива appMovable присваивается элементу HTML, но элемент не ведет себя в соответствии с назначенной ему директивой.

Есть ли что-то еще, что нужно сделать, или есть альтернативный вариант для правильной работы директивы с динамически создаваемыми элементами HTML?

...