Angular按钮指令错误地附加子元素

huangapple go评论58阅读模式
英文:

Angular button directive incorrectly appending child element

问题

我使用这个按钮加载指令。我的问题是,当使用该指令时,它将进度加载器附加在按钮下方,而不是在按钮内部。

我已经在this.elementRef.nativeElement上进行了控制台日志记录,它返回了正确的按钮元素。

button-loader.directive.ts

import { Directive, ElementRef, Input, ViewContainerRef, Renderer2 } from '@angular/core';
import { MatButton } from '@angular/material/button';
import { MatProgressBar } from '@angular/material/progress-bar';

@Directive({
  selector: '[buttonLoader]'
})
export class ButtonLoaderDirective {
  progressElement: any;

  @Input() set buttonLoader(value: boolean) {
    this.toggle(value);
  }

  constructor(
    private viewContainerRef: ViewContainerRef, 
    private matButton: MatButton, 
    private renderer: Renderer2, 
    private elementRef: ElementRef) {
    this.loadComponent();
  }

  loadComponent() {
    this.viewContainerRef.clear();
    
    // 创建组件
    const matProgress = this.viewContainerRef.createComponent(MatProgressBar);
    
    matProgress.instance.mode = 'indeterminate';
    
    // 将它移动
    this.progressElement = matProgress.injector.get(MatProgressBar)._elementRef.nativeElement
    
    this.renderer.appendChild(this.elementRef.nativeElement, this.progressElement);

    // 添加自定义类
    this.elementRef.nativeElement.classList.add('mat-load-button');
  }

  toggle(condition: boolean) {
    condition ? this.show() : this.hide()
  }

  show() {
    this.progressElement.style.opacity = '0.7';
    this.matButton.disabled = true;
  }

  hide() {
    this.progressElement.style.opacity = '0';
    this.matButton.disabled = false;
  }

}

HTML

<button 
    [buttonLoader]="true"
    mat-raised-button 
    color="primary"
>
Save
</button>

当前的显示方式

Angular按钮指令错误地附加子元素

这是我想要的显示方式

Angular按钮指令错误地附加子元素

英文:

I'm using this loading directive for a button. My problem is when using the directive it appends the progress loader below the button, not inside of it.

I've console logged the this.elementRef.nativeElement and it returns the correct button element.

button-loader.directive.ts

import { Directive, ElementRef, Input, ViewContainerRef, Renderer2 } from &#39;@angular/core&#39;;
import { MatButton } from &#39;@angular/material/button&#39;;
import { MatProgressBar } from &#39;@angular/material/progress-bar&#39;;
@Directive({
selector: &#39;[buttonLoader]&#39;
})
export class ButtonLoaderDirective {
progressElement: any;
@Input() set buttonLoader(value: boolean) {
this.toggle(value);
}
constructor(
private viewContainerRef: ViewContainerRef, 
private matButton: MatButton, 
private renderer: Renderer2, 
private elementRef: ElementRef) {
this.loadComponent();
}
loadComponent() {
this.viewContainerRef.clear();
// Create Component
const matProgress = this.viewContainerRef.createComponent(MatProgressBar);
matProgress.instance.mode = &#39;indeterminate&#39;;
// Move it
this.progressElement = matProgress.injector.get(MatProgressBar)._elementRef.nativeElement
this.renderer.appendChild(this.elementRef.nativeElement, this.progressElement);
// Add custom class
this.elementRef.nativeElement.classList.add(&#39;mat-load-button&#39;);
}
toggle(condition: boolean) {
condition ? this.show() : this.hide()
}
show() {
this.progressElement.style.opacity = &#39;0.7&#39;;
this.matButton.disabled = true;
}
hide() {
this.progressElement.style.opacity = &#39;0&#39;;
this.matButton.disabled = false;
}
}

HTML

&lt;button 
[buttonLoader]=&quot;true&quot;
mat-raised-button 
color=&quot;primary&quot;
&gt;
Save
&lt;/button&gt;

Currently how it looks

Angular按钮指令错误地附加子元素

Angular按钮指令错误地附加子元素

Here's how I want it to look

Angular按钮指令错误地附加子元素

Angular按钮指令错误地附加子元素

答案1

得分: 2

您的指令已经生效。progressbar 具有正确的“parent”。我只修改了 progressbar 的样式,添加了 position: absolute; 以及当前位置和宽度:

更新后的指令

import { Directive, ElementRef, Input, ViewContainerRef, Renderer2 } from '@angular/core';
import { MatButton } from '@angular/material/button';
import { MatProgressBar } from '@angular/material/progress-bar';

@Directive({
  selector: '[buttonLoader]'
})
export class ButtonLoaderDirective {
  progressElement: any;

  @Input() set buttonLoader(value: boolean) {
    this.toggle(value);
  }

  constructor(
    private viewContainerRef: ViewContainerRef, 
    private matButton: MatButton, 
    private renderer: Renderer2, 
    private elementRef: ElementRef) {
    this.loadComponent();
  }

  loadComponent() {
    this.viewContainerRef.clear();
    
    // 创建组件
    const matProgress = this.viewContainerRef.createComponent(MatProgressBar);
    
    matProgress.instance.mode = 'indeterminate';
    
    // 移动组件
    this.progressElement = matProgress.injector.get(MatProgressBar)._elementRef.nativeElement

    this.renderer.appendChild(this.elementRef.nativeElement, this.progressElement);


    // 添加自定义类
    this.elementRef.nativeElement.classList.add('mat-load-button');
  }

  toggle(condition: boolean) {
    condition ? this.show() : this.hide()
  }

  show() {
    this.progressElement.style.opacity = '0.7';
    this.progressElement.style.position = "absolute"
    this.matButton.disabled = true;
    this.progressElement.style.bottom = "10px";
    this.progressElement.style.width = "calc(100% - 10px)";
  }

  hide() {
    this.progressElement.style.opacity = '0';
    this.matButton.disabled = false;
  }
}

HTML

  <button
    style="height: 80px"
    mat-raised-button
    color="primary"
    [buttonLoader]="true"
  >
    My Button
  </button>

这是完整的 Stackblitz 示例。

这是结果图像:

Angular按钮指令错误地附加子元素

英文:

Your directive works. The progressbar has the right "parent". I only have modified the progressbar style with position: absolute; and the current position + width:

Updated directive

import { Directive, ElementRef, Input, ViewContainerRef, Renderer2 } from &#39;@angular/core&#39;;
import { MatButton } from &#39;@angular/material/button&#39;;
import { MatProgressBar } from &#39;@angular/material/progress-bar&#39;;
@Directive({
selector: &#39;[buttonLoader]&#39;
})
export class ButtonLoaderDirective {
progressElement: any;
@Input() set buttonLoader(value: boolean) {
this.toggle(value);
}
constructor(
private viewContainerRef: ViewContainerRef, 
private matButton: MatButton, 
private renderer: Renderer2, 
private elementRef: ElementRef) {
this.loadComponent();
}
loadComponent() {
this.viewContainerRef.clear();
// Create Component
const matProgress = this.viewContainerRef.createComponent(MatProgressBar);
matProgress.instance.mode = &#39;indeterminate&#39;;
// Move it
this.progressElement = matProgress.injector.get(MatProgressBar)._elementRef.nativeElement
this.renderer.appendChild(this.elementRef.nativeElement, this.progressElement);
// Add custom class
this.elementRef.nativeElement.classList.add(&#39;mat-load-button&#39;);
}
toggle(condition: boolean) {
condition ? this.show() : this.hide()
}
show() {
this.progressElement.style.opacity = &#39;0.7&#39;;
this.progressElement.style.position = &quot;absolute&quot;
this.matButton.disabled = true;
this.progressElement.style.bottom = &quot;10px&quot;;
this.progressElement.style.width = &quot;calc(100% - 10px)&quot;
}
hide() {
this.progressElement.style.opacity = &#39;0&#39;;
this.matButton.disabled = false;
}
}

HTML

  &lt;button
style=&quot;height: 80px&quot;
mat-raised-button
color=&quot;primary&quot;
[buttonLoader]=&quot;true&quot;
&gt;
My Button
&lt;/button&gt;

Here is the complete Stackblitz example.

Here the result:

Angular按钮指令错误地附加子元素

huangapple
  • 本文由 发表于 2023年3月3日 23:03:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定