【问题标题】:I need to create a Angular directive to clear content entered in input field in icon button click我需要创建一个 Angular 指令来清除在图标按钮单击的输入字段中输入的内容
【发布时间】:2020-10-18 10:20:27
【问题描述】:

我创建了一个指令,该指令仅在输入字段中有任何内容时才会显示清除按钮图标。我还需要清除按钮单击时输入的内容。

由于宿主元素本身没有被输入,所以值在指令内部设置为空,但没有反映在组件中。

HTML

<mat-form-field>
    <input matInput  #inputVal type="text" placeholder="Clearable input" [(ngModel)]="value" />
    <mat-icon [clearInput]= "inputVal.value" class="suffix" matSuffix >Close</mat-icon>
</mat-form-field>

指令

@Directive({
  selector: '[clearInput]',
  exportAs: 'clearInput'
})
export class clearInputDirective implements OnChanges{
   
    @Input('clearInput') inputValue: any;
    constructor(private el: ElementRef, private renderer:Renderer2) {
      
  }
  @HostListener('click') onClick() {
    this.inputValue = null;
  }

  ngOnChanges(changes: SimpleChanges){
    if(changes.inputValue){
   
     if(this.inputValue){
        this.renderer.setStyle(this.el.nativeElement, 'display', 'block');
       }
       else {
        this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
       }
    }
  }
}

【问题讨论】:

  • 您是否在HTML 中添加了指令选择器?
  • &lt;input clearInput type="text" class="form-control" formControlName="Todo" /&gt;
  • @Wasim 如果我在输入中添加选择器,它甚至不会显示初始值
  • 你在使用表单控件吗?
  • 该指令的实际实现可以使用表单控件

标签: angular angular-material angular-directive


【解决方案1】:

这个问题符合。对我来说 clearInput 没有绑定到您的 inputVal 它只是取一个值并在指令中相应地采取行动。 对于您的工作方法,您需要在指令中完整引用 inputVal

现在它只是一个原始值,这就是为什么当你将值更改为 null 时,它只是在指令级别。

[编辑]

试试下面的代码。 - 当您使用 ngmodel 时,我们需要 ngmodel 的参考

<div class="input">
 <input matInput  clearInput [clearInput]= "value" #inputVal type="text" placeholder="Clearable input" [(ngModel)]="value" />
<div class="alwaysCloseButtonWillBethere" 
    matSuffix >Close</div>
</div>

clear 指令 -- 只是我采用了一个像 html 一样的常量,就像 div[input , close] 当你点击关闭时输入会变空

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

@Directive({
  selector: '[clearInput]',
  exportAs: 'clearInput'
})
export class ClaerinputDirective implements OnChanges , OnInit , OnDestroy{
   
    @Input('clearInput') inputValue: any;
    constructor(private el: ElementRef, private renderer:Renderer2 , private model: NgModel) {
      
  }

  ngOnInit(){
     this.el.nativeElement.parentNode.children[1].addEventListener('click', () =>{
       this.model.control.reset();
     })
  }

  ngOnChanges(changes: SimpleChanges){
   if(changes.inputValue){
      if(this.inputValue){
       this.renderer.setStyle(this.el.nativeElement.parentNode.children[1], 'display', 'block');
       }
       else {
        this.renderer.setStyle(this.el.nativeElement.parentNode.children[1], 'display', 'none');
       }
   }
  }

  ngOnDestroy() {
     this.el.nativeElement.parentNode.children[1].removeEventListener('click',null
     );
  }
}

如果 dom 节点不是静态的,则根据类名在其下方使用我已取的类名 --- alwaysCloseButtonWillBethere

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

@Directive({
  selector: '[clearInput]',
  exportAs: 'clearInput'
})
export class ClaerinputDirective implements OnChanges , OnInit , OnDestroy{
   
    @Input('clearInput') inputValue: any;
    nodeToHideAndShow: HTMLElement;
    constructor(private el: ElementRef, private renderer:Renderer2 , private model: NgModel) {
      
  }

  getNode(){
   if(!this.nodeToHideAndShow){
     this.nodeToHideAndShow = this.el.nativeElement.parentNode.querySelector('.alwaysCloseButtonWillBethere');
    }

  }
  ngOnInit(){
    this.getNode();
    if(!this.nodeToHideAndShow){
      // alert('Add a class  alwaysCloseButtonWillBethere')
    } else {
      console.log('d');
      this.nodeToHideAndShow.addEventListener('click', () => {
       this.model.control.reset();
     })
    }
     
  }

  ngOnChanges(changes: SimpleChanges){
   if(changes.inputValue){
     this.getNode();
      if(this.inputValue){
       this.renderer.setStyle( this.nodeToHideAndShow, 'display', 'block');
       }
       else {
        this.renderer.setStyle( this.nodeToHideAndShow, 'display', 'none');
       }
   }
  }

  ngOnDestroy() {
    if( this.nodeToHideAndShow){
          this.nodeToHideAndShow.removeEventListener('click',null);
      }
  }
}

【讨论】:

  • 将输入属性修改为 [val]="inputVal.value" 后(因为单击图标后没有隐藏),component.ts 中的输入字段值没有更新。它只在 html 模板中得到更新。
  • 我猜因为 ngmodel 在那里,那么当前的植入将不起作用,我们需要一个 NgModel 实例在指令中然后才能工作
  • @sneha 我已经更新了代码,请检查一下这个实现
  • 如果指令用户更改 dom heirarcy 或使用 mat 表单字段然后使用 this.el.nativeElement.parentNode.children[1] 获取 alwaysCloseButtonWillBethere 将不起作用。
  • 另外,您的第一种方法更可行,因为我需要在按钮中添加指令。只需要找出方法来改变模型中的输入值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 2017-05-30
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
相关资源
最近更新 更多