最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to append after last child element with Angular Renderer2? - Stack Overflow

programmeradmin5浏览0评论

I'm trying to append a button after an input field with an Angular7 directive. The problem is that the Renderer2 method appendChild is placing the button before the input field.

Button before input field image

import { Directive, ElementRef, Input , HostListener, Renderer2, OnInit, OnDestroy } from '@angular/core';

@Directive({
  selector: '[appInlineEdit2]'
})
export class InlineEdit2Directive {

  @Input() value: any;
  private spanElement: Node;
  private spanText: Node;
  // private children: Node[];

  constructor(private el: ElementRef,
    public renderer: Renderer2) {
      this.spanElement = this.renderer.createElement('span');
      // this.spanText = this.renderer.createText('dummy_span');
      // this.renderer.appendChild(this.spanElement, this.spanText);
      this.renderer.setAttribute(this.spanElement, 'id', 'anchor');
      this.renderer.appendChild(this.el.nativeElement, this.spanElement);
      // this.renderer.insertBefore(this.el.nativeElement, this.spanElement, null);
      this.renderer.listen(this.spanElement, 'click', this.onClick.bind(this));

      const button = this.renderer.createElement('button');
      this.renderer.setAttribute(button, 'type', 'button');
      this.renderer.addClass(button, 'btn');
      this.renderer.addClass(button, 'btn-primary');
      const buttonText = this.renderer.createText('OK');
      this.renderer.appendChild(button, buttonText);
      this.renderer.listen(button, 'click', this.onClickOK.bind(this));
      this.renderer.appendChild(this.el.nativeElement, button);
      // this.renderer.insertBefore(this.el.nativeElement, button, null);
    }

    ngOnInit() {
      console.log(this.el.nativeElement.childNodes);
      // this.showMode();
    }
}

And in the template:

<div class="input-group col-6" appInlineEdit2 [value]="model">
    <input type="text" class="form-control" placeholder="Recipient's username"
        [(ngModel)]="model" aria-label="Recipient's username" aria-describedby="basic-addon2">
</div>

I expect the button to be after the input field in the DOM.

I'm trying to append a button after an input field with an Angular7 directive. The problem is that the Renderer2 method appendChild is placing the button before the input field.

Button before input field image

import { Directive, ElementRef, Input , HostListener, Renderer2, OnInit, OnDestroy } from '@angular/core';

@Directive({
  selector: '[appInlineEdit2]'
})
export class InlineEdit2Directive {

  @Input() value: any;
  private spanElement: Node;
  private spanText: Node;
  // private children: Node[];

  constructor(private el: ElementRef,
    public renderer: Renderer2) {
      this.spanElement = this.renderer.createElement('span');
      // this.spanText = this.renderer.createText('dummy_span');
      // this.renderer.appendChild(this.spanElement, this.spanText);
      this.renderer.setAttribute(this.spanElement, 'id', 'anchor');
      this.renderer.appendChild(this.el.nativeElement, this.spanElement);
      // this.renderer.insertBefore(this.el.nativeElement, this.spanElement, null);
      this.renderer.listen(this.spanElement, 'click', this.onClick.bind(this));

      const button = this.renderer.createElement('button');
      this.renderer.setAttribute(button, 'type', 'button');
      this.renderer.addClass(button, 'btn');
      this.renderer.addClass(button, 'btn-primary');
      const buttonText = this.renderer.createText('OK');
      this.renderer.appendChild(button, buttonText);
      this.renderer.listen(button, 'click', this.onClickOK.bind(this));
      this.renderer.appendChild(this.el.nativeElement, button);
      // this.renderer.insertBefore(this.el.nativeElement, button, null);
    }

    ngOnInit() {
      console.log(this.el.nativeElement.childNodes);
      // this.showMode();
    }
}

And in the template:

<div class="input-group col-6" appInlineEdit2 [value]="model">
    <input type="text" class="form-control" placeholder="Recipient's username"
        [(ngModel)]="model" aria-label="Recipient's username" aria-describedby="basic-addon2">
</div>

I expect the button to be after the input field in the DOM.

Share Improve this question asked Jul 9, 2019 at 17:34 Nikolay StefanovNikolay Stefanov 932 silver badges6 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

The problem with your code is that you are executing Renderer2 related logic in constructor. Constructor is called during ponent creation and at that moment ponent DOM has not been initialized yet, which means ElementRef and nativeElement exists somewhere but not in the DOM yet. That's why you are experiencing such ambiguous behavior.

See this post for further details.

So, placing Renderer2 related logic within ngOnInit solves your problem.

Here is a working demo https://stackblitz./edit/angular-ywn1ky

发布评论

评论列表(0)

  1. 暂无评论