What could be the issue, for example we have two list:

Parent component:

@Component({
selector: 'passenger-dashboard',
styleUrls: ['passenger-dashboard.component.scss'],
template: `
<div>
<passenger-count
[items]="passengers">
</passenger-count>
<div *ngFor="let passenger of passengers;">
{{ passenger.fullname }}
</div>
<passenger-detail
*ngFor="let passenger of passengers;"
[detail]="passenger"
(edit)="handleEdit($event)"
(remove)="handleRemove($event)">
</passenger-detail>
</div>
`
})
export class PassengerDashboardComponent implements OnInit {
passengers: Passenger[];
constructor() {}
ngOnInit() {
this.passengers = [{
id: ,
fullname: 'Stephen',
checkedIn: true,
checkInDate: ,
children: null
}, {
id: ,
fullname: 'Rose',
checkedIn: false,
checkInDate: null,
children: [{ name: 'Ted', age: },{ name: 'Chloe', age: }]
}, {
id: ,
fullname: 'James',
checkedIn: true,
checkInDate: ,
children: null
}, {
id: ,
fullname: 'Louise',
checkedIn: true,
checkInDate: ,
children: [{ name: 'Jessica', age: }]
}, {
id: ,
fullname: 'Tina',
checkedIn: false,
checkInDate: null,
children: null
}];
}
handleEdit(event: Passenger) {
this.passengers = this.passengers.map((passenger: Passenger) => {
if (passenger.id === event.id) {
passenger = Object.assign({}, passenger, event);
}
return passenger;
});
}
handleRemove(event: Passenger) {
this.passengers = this.passengers.filter((passenger: Passenger) => {
return passenger.id !== event.id;
});
}
}

Child component:

@Component({
selector: 'passenger-detail',
styleUrls: ['passenger-detail.component.scss'],
template: `
<div>
<span class="status" [class.checked-in]="detail.checkedIn"></span>
<div *ngIf="editing">
<input
type="text"
[value]="detail.fullname"
(input)="onNameChange(name.value)"
#name>
</div>
<div *ngIf="!editing">
{{ detail.fullname }}
</div>
<div class="date">
Check in date:
{{ detail.checkInDate ? (detail.checkInDate | date: 'yMMMMd' | uppercase) : 'Not checked in' }}
</div>
<div class="children">
Children: {{ detail.children?.length || }}
</div>
<button (click)="toggleEdit()">
{{ editing ? 'Done' : 'Edit' }}
</button>
<button (click)="onRemove()">
Remove
</button>
</div>
`
})
export class PassengerDetailComponent implements OnInit { @Input()
detail: Passenger; @Output()
edit: EventEmitter<any> = new EventEmitter(); @Output()
remove: EventEmitter<any> = new EventEmitter(); editing: boolean = false; constructor() {} ngOnInit() {
console.log('ngOnInit');
} onNameChange(value: string) {
this.detail.fullname = value;
} toggleEdit() {
if (this.editing) {
this.edit.emit(this.detail);
}
this.editing = !this.editing;
}
onRemove() {
this.remove.emit(this.detail);
}
}

They both display list of "passengers".

What will happens that when we change the "passenger" value in 'passenger-detail' component. It will using '(edit)' event to update parent component's 'passengers' variable.

Both changes happens in the same time.

But what we really want is, until child component click "Done" button then parent component get udpate.

So what we can do is using 'ngOnChanges' in child component to break Javascript object reference (this.detail, which marked in yellow background).

export class PassengerDetailComponent implements OnChanges, OnInit {

  constructor() {}

  ngOnChanges(changes) {
if (changes.detail) {
this.detail = Object.assign({}, changes.detail.currentValue);
}
console.log('ngOnChanges');
} onNameChange(value: string) {
this.detail.fullname = value;
} ...
}

We use 'Object.assign' to create a new 'this.detail' object reference.

And because of this new creation, it actually breaks the reference of 'this.detail'.

And only when click "Done" button, the deatial will be sent to the parent component.

[Angular] Using ngOnChanges lifeCycle hook to break object reference的更多相关文章

  1. [React] Update State Based on Props using the Lifecycle Hook getDerivedStateFromProps in React16.3

    getDerivedStateFromProps is lifecycle hook introduced with React 16.3 and intended as a replacement ...

  2. [React] Capture values using the lifecycle hook getSnapshotBeforeUpdate in React 16.3

    getSnapshotBeforeUpdate is a lifecycle hook that was introduced with React 16.3. It is invoked right ...

  3. [MST] Loading Data from the Server using lifecycle hook

    Let's stop hardcoding our initial state and fetch it from the server instead. In this lesson you wil ...

  4. ArcGIS AddIN异常之:object reference not set to an instance of an object

    异常出现在 frmDownload frd = new frmDownload(); frd.ShowDialog(); 在ArcMap中能正常弹出窗体,点击按钮时显示此异常:object refer ...

  5. Java中对不变的 data和object reference 使用 final

    Java中对不变的 data和object reference 使用 final 许多语言都提供常量数据的概念,用来表示那些既不会改变也不能改变的数据,java关键词final用来表示常量数据.例如: ...

  6. Attempt to write to field 'android.support.v4.app.FragmentManagerImpl android.support.v4.app.Fragment.mFragmentManager' on a null object reference

    E/AndroidRuntime﹕ FATAL EXCEPTION: mainProcess: org.example.magnusluca.drawertestapp, PID: 3624java. ...

  7. Azure Sphere–“Object reference not set to an instance of an object” 解决办法

    在开发Azure Sphere应用时,如果出现项目无法编译,出现“Object reference not set to an instance of an object”时,必须从下面两个方面进行检 ...

  8. Visual Studio 2015打开ASP.NET MVC的View提示"Object reference not set to an instance of an object"错误的解决方案

    使用Visual Studio 2013打开没有问题,但Visual Studio 2015打开cshtml就会提示"Object reference not set to an insta ...

  9. Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayShowHomeEnabled(boolean)' on a null object reference

    /********************************************************************************* * Caused by: java ...

随机推荐

  1. Python中对于GIL全局解释器锁的一点理解

    GIL全局解释器锁 python最初开发时,开发人只考虑到了单核CPU的,为解决多线程运算之间的数据完整性和状态同步选择了加锁的方式.即GIL锁. 而目前的CPU都有多个核心,在运行python的某个 ...

  2. Spring学习总结(6)——Spring之核心容器bean

    一.Bean的基础知识 1.在xml配置文件中,bean的标识(id 和 name) id:指定在benafactory中管理该bean的唯一的标识.name可用来唯一标识bean 或给bean起别名 ...

  3. JavaScript学习总结(6)——js弹出框、对话框、提示框、弹窗总结

    一.JS的三种最常见的对话框 [javascript] view plaincopy //====================== JS最常用三种弹出对话框 =================== ...

  4. hdu 2795 Billboard(线段树单点更新)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. GitHub上常用命令(工作中几乎每天用到的命令)

    查看自己当前分支 git branch 查看远程和本地分支 git branch -a 查看origin下的分支 git config -vv git config --lis 创建分支 git br ...

  6. php网页跳转无法获取session值

    今日编写项目,需要在跳转后的页面获取session值进行自动登录操作,但是明明在传输页面可以打印出session值,但在接受页面却显示session值为空,经确认脚本中的session_start() ...

  7. GO语言学习(十二)Go 语言函数

    Go 语言函数 函数是基本的代码块,用于执行一个任务. Go 语言最少有个 main() 函数. 你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务. 函数声明告诉了编译器函数的名称,返回 ...

  8. synchronized和ReentrantLock区别

    一.什么是sychronized sychronized是java中最基本同步互斥的手段,可以修饰代码块,方法,类. 在修饰代码块的时候需要一个reference对象作为锁的对象. 在修饰方法的时候默 ...

  9. 如何把传统写法改成框架形式 es6

    每天思考的问题: 1.什么是组件 2.什么是插件 3.如何把传统写法改成框架形式 4.前端为什么要使用框架,使用框架的好处是什么? Image.png http://www.zhihu.com/que ...

  10. Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolExecutor例子——了解如何创建一个周期任务)

    Welcome to the Java Scheduler Example. Today we will look into ScheduledExecutorService and it's imp ...