I have a component that needs to track changes to the data source. The parent component provides data via async pipe. If the data source is changed (item added or deleted), then ngOnChanges does not fires.
Help to deal with the problem.
@Component({
selector: 'app-todo',
template: `
<div>
<button (click)="addTodo()">Add Item</button><br />
<div *ngFor="let todo of todos">
{{ todo.value }} <button (click)="deleteTodo(todo.id)">x</button>
</div>
</div>
`
})
export class TodoComponent implements OnChanges {
@Input() todos: Todo[];
constructor(private todoService: TodoService) {
}
addTodo() {
this.todoService.create({ value: 'value '+this.todos.length });
}
ngOnChanges(changes: { [key: string]: SimpleChange })
{
if (changes['todos']) {
console.log('todos changed')
}
}
deleteTodo(todoId: number) {
this.todoService.remove(todoId);
}
}
Parent component:
@Component({
selector: 'my-app',
template: `
<h1>Angular Observable Data Services</h1>
<p>Only implimented a simple post and delete</p>
<h3>Component 1</h3>
<app-todo [todos]='todos | async'></app-todo>
<br /><br />
<h3>Component 2</h3>
<app-todo [todos]='todos | async'></app-todo>
`
})
export class AppComponent {
todos: Observable<Todo[]>;
constructor(private todoService: TodoService){
this.todos = this.todoService.todos;
this.todoService.loadAll();
}
}
You're hitting shallow/deep clone problem.
For example, in your service create
method you copy this.dataStore
but then you reuse its todos
property which is not copied, it stays the same reference thus there is nothing to trigger onChange
.
what you want to do is something like:
this.dataStore.todos.push(something); //this mutates an array
const x = [...this.dataStore.todos];`//clones actual array
and feed that into your BehaviorSubject.next(x)
useful ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.