首页 > 解决方案 > Angular 6:OnChanges 不适用于异步管道

问题描述

我有一个组件需要跟踪数据源的更改。父组件通过异步管道提供数据。如果数据源更改(添加或删除项目),则不会触发 ngOnChanges。

帮助处理问题。

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

父组件:

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

堆栈闪电战

标签: angular

解决方案


您遇到了浅/深克隆问题。

例如,在您的服务create方法中,您复制this.dataStore但随后重用其todos未复制的属性,它保持相同的引用,因此没有什么可以触发onChange

你想要做的是这样的:

this.dataStore.todos.push(something); //this mutates an array
const x = [...this.dataStore.todos];`//clones actual array

并将其输入您的BehaviorSubject.next(x)

有用的参考: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone


推荐阅读