简体   繁体   中英

Angular 6: OnChanges does not work with async pipe

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();
  }
}

stackblitz

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM