WEB全栈工程师视频回放 (34.2)——Angular 双向数据绑定 (ngModel)应用

应用场景
WEB全栈工程师视频回放 (34.2)——Angular 双向数据绑定 (ngModel)应用_第1张图片
image.png

在视频回放的第 34 讲 34.2 节, 讲了Angular 双向数据绑定 (ngModel)的应用。 在工程示例中,出现了一个诡异的现象, 就是 child component 的编辑数据与 parent component 列表的数据出现了同步,正常情况下,应该是只有点击 “添加商品”后, 商品列表才会更新, 这是什么原因造成的呢?

为什么出现错误的判断?

既然是双向数据绑定, 就意味着只要数据发生变化,就会触发相应的onChange事件, 由此下意识地得出结论: 是 ngModel 造成的, 从而对 ngModel进行了批判。接着对工程进行了改造, 用 模板引用变量(template reference variable)解决了这个问题。 问题是解决了,但问题产生判断真正原因真的是 ngModel 造成的吗?

问题解读与剖析

// product-create.component.ts 
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Product } from "../product";

@Component({
  selector: 'app-product-create',
  templateUrl: './product-create.component.html',
  styleUrls: ['./product-create.component.css']
})
export class ProductCreateComponent implements OnInit {

  @Output()  created = new EventEmitter();
  product : Product;
  constructor() { 
    this.product = new Product;
  }
  ngOnInit() {
  }
  createProduct( ){
    this.created.emit( this.product );
    console.log("子组件发射的数据=",this.product ); 
  }
}

既然怀疑是 ngModel 触发的, 那么,在 createProduct() 方法中,添加一个log,如下:

createProduct( ){
this.created.emit( this.product );
console.log("子组件发射的数据=",this.product );

}

重新运行。 在创建商品的编辑框中,编辑数据时,发现 在浏览器的console中,数据并没有发生变化,这说明, ngModel 在数据变化时,没有触发 createProduct( ) 方法。

找到真正原因

出现bug, 调试是最好的方法。 商品(product) 存放在一个数组中, log 如下:

WEB全栈工程师视频回放 (34.2)——Angular 双向数据绑定 (ngModel)应用_第2张图片
image.png

前4项是初始化的商品列表, 从第5项开始,是新添加的商品。

发现一个奇怪的现象: 这个商品列表数组存放的是 Product,也就是说,存放了一个新添加的对象,而这个对象正是 ngModel 对象

import { Component, OnInit } from '@angular/core';
import { Product } from "../product";
@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {

  products: Product[];
  myProduct: any; 
  constructor() {
    this.products = new Array ();    // 必须的,否则报错, 创建对象的实例
   }
  ngOnInit() {
    this.products = [
      { title: "第 1 件商品", price: 11 },
      { title: "第 2 件商品", price: 22 },
      { title: "第 3 件商品", price: 33 },
      { title: "第 4 件商品", price: 44 },
      { title: "第 5 件商品", price: 55 },
    ];
    }

  addProduct( product: Product ){
   this.products.push(product);
  console.log("收到了来自 child 组件的数据",this.products);
   }

}

关键代码:

addProduct( product: Product ){
this.products.push(product);
}

真正的原因在于:

子组件 发射的对象是:

this.created.emit( this.product );

父组件 接收到这个product 对象后, 进行了压栈 ,如下:
> this.products.push(product);

解决方案

不再存储这个与 ngModel 关联的对象,而是重新构建一个Product 对象, 代码改造如下:

// product-list.component.ts
addProduct( product: Product ){
    this.myProduct = {
    title :  product.title,
    price:  product.price
   }
   this.products.push( this.myProduct );
}

运行测试,之前的诡异现象不见了:

WEB全栈工程师视频回放 (34.2)——Angular 双向数据绑定 (ngModel)应用_第3张图片
image.png

小结

用到 ngModel 时, 要特别注意。 从以上代码可以看出, ngModel 的双向数据绑定,是建立在一个共享内存(地址)的基础之上的。 所以才出现,一变俱变!

你可能感兴趣的:(WEB全栈工程师视频回放 (34.2)——Angular 双向数据绑定 (ngModel)应用)