数字输入的角度自定义指令需要访问父反应表单 - FormGroup 和 FormContols

Posted

技术标签:

【中文标题】数字输入的角度自定义指令需要访问父反应表单 - FormGroup 和 FormContols【英文标题】:Angular custom directive on number input needs access to parent reactive form - FormGroup and FormContols 【发布时间】:2022-01-03 14:47:01 【问题描述】:

我编写了一个 Angular 自定义指令,将一些自定义按钮添加到数字输入到 stepUp()stepDown() 输入值。指令代码是这样的(我已经减少了代码)。

@Directive(
  selector: '[numberControls]'
)
export class NumberControlsDirective implements OnInit 

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

  ngOnInit(): void 
    this.createStuctureAndControls();
  

  createStuctureAndControls(): void 
    const parent = this.elementRef.nativeElement.parentNode;
    // okay, create the container div
    const containerElement = this.renderer.createElement('div');
    // now let's create a row to contain everything
    const firstRowElement = this.renderer.createElement('div');
    // let's put the original input in the first row div
    this.renderer.appendChild(firstRowElement, this.elementRef.nativeElement);
    // add the row to the container
    this.renderer.appendChild(containerElement, firstRowElement);
    // add the controls
    const controlsElement = this.renderer.createElement('div');
    const firstControl = this.renderer.createElement('div');
    const secondControl = this.renderer.createElement('div');
    // now put some content in the controls
    firstControl.innerhtml = '-'; // to decrease value
    secondControl.innerHTML = '+'; // to increase
    // add click events  
    firstControl.addEventListener('click', this.onClickDecrease.bind(this));
    secondControl.addEventListener('click', this.onClickIncrease.bind(this));
    // put the controls into the controlsElement
    this.renderer.appendChild(controlsElement, firstControl);
    this.renderer.appendChild(controlsElement, secondControl);
    // not put it in the first row
    this.renderer.appendChild(firstRowElement, controlsElement);
    // append to the dom
    this.renderer.appendChild(parent, containerElement);
    // Remove the directive attribute (not really necessary, but just to be clean)
    this.renderer.removeAttribute(this.elementRef.nativeElement, 'numberControls');
  

  /**
   * Method to increase value
   */
  onClickDecrease(): void 
    this.elementRef.nativeElement.stepDown();
  

  /**
   * Method to decrease value
   */
  onClickIncrease(): void 
    this.elementRef.nativeElement.stepUp();
  

现在我将指令添加到响应式表单中,这就是它在我的 html 文件中的样子。

<form [formGroup]="myReactiveForm" (ngSubmit)="onSubmit()" autocomplete="off">
  <input type="number" formControlName="numberOne" numberControls>
</form>

问题是,当我单击其中一个控件进行 stepUp 或 stepDown 时,输入的值会更新,但是我使用指令的反应式表单没有更新。我需要将表单标记为已触摸或已脏。我不确定如何访问包含该指令的FormGroupFormControl。我曾尝试在指令代码中使用FormGroupDirective,但这似乎不起作用。也不使用NgModel。我有点困惑如何更新父表单(如果存在)。有没有人对我如何在我的指令中访问父表单有任何想法或信息。提前致谢。

如果我的解释不好或令人困惑,请说出来,我会改写。

【问题讨论】:

您可以简单地将 formGroup 和 formControl 值作为 Input() 属性传递给指令。上下步可以使用patchValue()setValue()设置数据。 我按照你说的做了,问题解决了,谢谢! 【参考方案1】:

您可以在 numberControlsDirective 中注入NgControl 以获取父表单实例。

试试这个

export class NumberControlsDirective 
      constructor(private elementRef: ElementRef,
        private ngControl:NgControl,
        private renderer: Renderer2) 
      
    
      ngOnInit(): void 
        console.log(this.ngControl.control.parent);
        this.createStuctureAndControls();
      
    
    

【讨论】:

以上是关于数字输入的角度自定义指令需要访问父反应表单 - FormGroup 和 FormContols的主要内容,如果未能解决你的问题,请参考以下文章

如何以角度反应形式访问表单控件和表单组

通过使用指令模糊和加载表单上的角度数字格式,也不应该格式化 formControl 数据

如何从 AngularJS 中的自定义指令 * 使用自己的范围 * 访问父范围?

以角度将指令/输入传递给孩子的反应方式是啥?

如何在angular4中为来自ts的反应形式应用自定义指令?

在自定义 Angular 组件中访问 FormControl