从 Angular 指令获取 NgForm 实例

Getting a NgForm instance from an Angular directive

我正在尝试创建一种行为,其中附加到 preventFormChangesLoss 指令的所有表单都将运行,以便在表单发生更改时(如果不是 pristinesubmitted), 当用户想要离开时,页面会显示警告。

为此,我正在尝试获取我的指令以获取我的指令附加到的 NgForm 实例。 现在,我有

import { Directive, Input, ElementRef, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';

@Directive({
  selector: '[preventFormChangesLoss]'
})
export class PreventFormChangesLoss implements OnInit, AfterViewInit {
  private origin: string = '';

  @ViewChild('myForm') form : NgForm;

  constructor(private elRef: ElementRef) {
    console.log(this.elRef);
  }

  ngOnInit() {
    console.log(this.elRef, this.form);
  }

  ngAfterViewInit() {
    console.log(this.elRef, this.form); // shows the native element, + 'undefined'
  }
}

我将它与

一起使用
<form preventFormChangesLoss #myForm="ngForm">
...
</form>

不幸的是,这不起作用,我也希望我的指令无需执行 #myForm="ngForm" 部分即可获取 NgForm 实例,以便我可以根据需要命名我的表单并保持此行为分开。

我该怎么做,有人可以指出我在文档中的正确位置吗?

您不能像那样抓取表单元素,因为它不是指令 视图 的一部分。相反,你应该直接注入它。

import { Directive, Input, ElementRef, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

@Directive({
  selector: '[preventFormChangesLoss]'
})
export class PreventFormChangesLoss implements OnInit {
  private origin: string = '';

  constructor(private ngForm: NgForm) {
    console.log(this.ngForm);
  }

  ngOnInit() {
    console.log(this.ngForm)
  }
}

这将允许您从指令中操作和订阅特定 Angular 增强的 <form> 的事件,因此您只能像这样使用它:

<form preventFormChangesLoss>
...
</form>

不是按照您的设计,而是提示:既然您说过要为 所有 表单执行此操作,那么将选择器更改为 [= 可能更简单13=]。然后你只需要将模块导入你的共享模块,所有你已经创建的表单将具有此功能。如果您想在特定表单上禁用它,可以使用 <form allowFormChangesLoss>,从而反转 "default" 行为。