To work around a problem with dragula I thought I add and remove the elements from the DOM instead. The goal is to use some placeholder elements to get the layout I want (left aligned elements in a centered container at all resolutions). These placeholder elements have to be placed at the end!
I tried the following approaches:
- ngIf: problem here is that it can happen that the invisible elements are not placed at the end. Through drag & drop it can happen that the dropped element is on the last place and the invisible elements are between.
- push elements on the array: here I tried to add the class invisible with the help of the ngClass directive, but it didn't update it correctly, when I set my boolean variable while pushing items on the array. The class was never applied.
ElementRef
: removing an element from the DOM worked, but I didn't figured out how to add oneRenderer2
: my current approach, whereremoveChild()
only removes one child despite it is called a second time
Template:
<div #button_area class="button_area" dragula="cards" [dragulaModel]="cards" (dragulaModelChange)="cards = $event">
<div *ngFor="let c of cards" id="{{ 'card-' + c.id }}" [ngClass]="calculateClasses(c)" [ngStyle]="calculateStyles(c)" (click)="onSelect($event, c)">
<!-- some irrelevant html code -->
</div>
</div>
Typescript:
@ViewChild('button_area') private buttonAreaElement: ElementRef;
constructor(public dragulaService: DragulaService,
private renderer: Renderer2) {
// something irrelevant
}
addPlaceholderElements() {
const placeholder = this.buttonAreaElement.nativeElement.querySelector('.invisible');
if (placeholder === null) {
const placeholder1 = this.renderer.createElement('div');
this.renderer.addClass(placeholder1, 'card');
this.renderer.addClass(placeholder1, 'invisible');
this.renderer.appendChild(this.buttonAreaElement.nativeElement, placeholder1);
const placeholder2 = this.renderer.createElement('div');
this.renderer.addClass(placeholder2, 'card');
this.renderer.addClass(placeholder2, 'invisible');
this.renderer.appendChild(this.buttonAreaElement.nativeElement, placeholder2);
}
}
removePlaceholderElements() {
const placeholder1 = this.buttonAreaElement.nativeElement.querySelector('.invisible');
if (placeholder1 !== null) {
this.renderer.removeChild(this.buttonAreaElement.nativeElement, placeholder1);
}
const placeholder2 = this.buttonAreaElement.nativeElement.querySelector('.invisible');
if (placeholder2 !== null) {
this.renderer.removeChild(this.buttonAreaElement.nativeElement, placeholder2);
}
}
As you can see I use the querySelector()
method for this. placeholder2 is found, but not removed from the DOM. But why?
I'm using Angular v. 7.2.5.
Edit:
Here is the MVCE. There the issue with the deletion doesn't occur. Haven't figured out what the difference is ... Why doesn't removeChild()
remove the child? Is this a timing issue?