Javascript 警告:ngModel与formControlName位于同一表单字段中

Javascript 警告:ngModel与formControlName位于同一表单字段中,javascript,angular,Javascript,Angular,在执行代码时,我没有得到任何错误;单击“更新”按钮时出现问题。 换句话说,我收到以下通知: 看起来您在与formControlName相同的表单字段上使用了ngModel。Angular v6中已不推荐使用ngModel输入属性和ngModelChange事件以及反应式表单指令,Angular v7中将删除这些支持。 product-list.component.html 产品 × 已删除产品数据 品名 产品品种 产品来源 行动 {{product.product_name} {{pro

在执行代码时,我没有得到任何错误;单击“更新”按钮时出现问题。 换句话说,我收到以下通知:

看起来您在与formControlName相同的表单字段上使用了ngModel。Angular v6中已不推荐使用ngModel输入属性和ngModelChange事件以及反应式表单指令,Angular v7中将删除这些支持。

product-list.component.html


产品
× 已删除产品数据 品名 产品品种 产品来源 行动 {{product.product_name} {{product.product_variation} {{product.product_origin} 删除 更新
更新产品 品名 产品品种 产品来源 Angular docs有一个描述了在决定使用哪种表单设计时需要考虑的不同因素:

反应式表单提供对底层表单对象模型的直接、显式访问。与模板驱动的表单相比,它们更健壮:更具可伸缩性、可重用性和可测试性。如果表单是应用程序的关键部分,或者您已经在使用反应模式构建应用程序,请使用反应表单

模板驱动表单依赖模板中的指令来创建和操作底层对象模型。它们对于向应用程序添加简单表单非常有用,例如电子邮件列表注册表单。它们很容易添加到应用程序中,但它们的伸缩性不如反应式表单。如果您有非常基本的表单需求和逻辑,可以单独在模板中进行管理,那么模板驱动的表单可能非常适合

我制作了一个小的angular应用程序,包含两种表单类型供参考。它不包括所有的铃铛和口哨每种形式提供,但希望它会让你移动。以下是供参考的

以下是模板驱动方法的示例:


产品名称产品种类产品来源
{{product.product_name}
{{product.product_variation}
{{product.product_origin}
更新
品名
产品品种
产品来源
更新
//模板驱动的.component.ts
导出类TemplateDrivenComponent{
productlist:Observable=this.productservice.getProductList();
i编辑=假;
产品标识:编号;
产品名称:字符串;
产品种类:细绳;
产品来源:字符串;
构造函数(私有productservice:productservice){}
setProductForm(id:编号){
const product:product=this.productservice.getProduct(id);
this.product\u id=product.product\u id;
this.product\u name=product.product\u name;
this.product_variation=product.product_variation;
this.product\u origin=product.product\u origin;
this.isEditing=true;
}
updateProduct(){
让产品:产品=新产品();
product.product\u id=此.product\u id;
product.product\u name=此.product\u名称;
product.product\u origin=此.product\u origin;
product.product\u variation=此.product\u variation;
this.productservice.updateProduct(产品);
这是resetForm();
}
重置表单(){
this.isEditing=false;
this.product_id=null;
this.product_name=null;
this.product_variation=null;
this.product_origin=null;
}
}
下面是一个反应式方法的示例:


品名
产品品种
产品来源
行动
{{product.product_name}
{{product.product_variation}
{{product.product_origin}
更新
品名
产品品种
产品来源
更新
//reactive.component.ts
导出类ReactiveComponent实现OnInit{
productupdateform:FormGroup;
productlist:Observable=this.productservice.getProductList()
i编辑=假;
构造函数(私有productservice:productservice,私有formBuilder:formBuilder){}
恩戈尼尼特(){
这是.initializeForm();
}
initializeForm(){
this.productupdateform=this.formBuilder.group({
产品ID:[0],
//template-driven.component.ts
export class TemplateDrivenComponent {
  productlist: Observable<Product[]> = this.productservice.getProductList();
  isEditing = false;
  product_id: number;
  product_name: string;
  product_variety: string;
  product_origin: string;

  constructor(private productservice: ProductService) { }

  setProductForm(id: number) {
    const product: Product = this.productservice.getProduct(id);
    this.product_id = product.product_id;
    this.product_name = product.product_name;
    this.product_variety = product.product_variety;
    this.product_origin = product.product_origin;
    this.isEditing = true;
  }

  updateProduct() {
    let product: Product = new Product();
    product.product_id = this.product_id;
    product.product_name = this.product_name;
    product.product_origin = this.product_origin;
    product.product_variety = this.product_variety;
    this.productservice.updateProduct(product);
    this.resetForm();
  }

  resetForm() {
    this.isEditing = false;
    this.product_id = null;
    this.product_name = null;
    this.product_variety = null;
    this.product_origin = null;
  }
}
//reactive.component.ts
export class ReactiveComponent implements OnInit {

  productupdateform: FormGroup;
  productlist: Observable<Product[]> = this.productservice.getProductList()
  isEditing = false;

  constructor(private productservice: ProductService, private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.initializeForm();
  }

  initializeForm() {
    this.productupdateform = this.formBuilder.group({
      theProductId: [0],
      theProductName: ['', Validators.required],
      theProductVariety: [''],
      theProductOrigin: ['']
    })
  }

  setProductForm(id: number) {
    const product = this.productservice.getProduct(id);
    this.productupdateform.patchValue({
      theProductId: product.product_id,
      theProductName: product.product_name,
      theProductVariety: product.product_variety,
      theProductOrigin: product.product_origin
    });
    this.productupdateform.updateValueAndValidity();
    this.isEditing = true;
  }

  updateProduct() {
    let product: Product = {
      product_id: this.productupdateform.get('theProductId').value,
      product_name: this.productupdateform.get('theProductName').value,
      product_variety: this.productupdateform.get('theProductVariety').value,
      product_origin: this.productupdateform.get('theProductOrigin').value
    }
    this.productservice.updateProduct(product);
    this.resetForm();
  }

  isFormValid() {
    return true;
  }

  resetForm() {
    this.isEditing = false;
    this.initializeForm();
  }
}