角度变化检测仅在连续的Ngrx存储更新中触发一次

时间:2018-04-13 17:45:14

标签: angular ngrx ngrx-store ngrx-effects

在以下场景中,角度变化检测不会以我期望的方式触发。我正在使用ngrx-store来保存我的应用程序状态。

  1. 最初,我有州S1。
  2. 我触发动作A1。侦听A1的reducer将状态更新为S2。效果触发动作A2。
  3. 侦听A2的减速器将状态更新回S1。
  4. 在上述情况下,存在两个状态更新(S1→S2→S1)。但是,在这一系列操作结束时,我的组件OnChange仅触发一次(S1 - > S1)。我正在使用带有异步管道的标准Observable和带@Input的子组件。

    @Component({
        selector: 'app-parent-component',
        template: `<app-time-entry [timeEntry]="timeEntry$ | async"></app-time-entry>`
    })
    export class ParentComponent {
        timeEntry$: Observable<TimeEntryRow>;
    
        constructor(private store: Store<AppState>) {
            this.timeEntry$ = this.store.select(state => state.time.timeEntry);
        }
    }
    
    @Component({
        selector: 'app-time-entry',
        template: `{{timeEntry.hours}}`
    })
    export class TimeEntryComponent {
        @Input() timeEntry: TimeEntry;
    }
    

    为什么在这种情况下只会发生一次变更检测?我已经验证我的状态是在每个操作之间正确更新,那么为什么绑定只更新一次?我希望异步管道可以两次传递已更改的状态,从而也会两次触发子组件OnChange。

    更新

    正如凯文所建议的,在效果中添加延迟会导致两个OnChanges按预期触发。这表明Angular&#34; tick&#34;两个状态更新完成后都会发生。

1 个答案:

答案 0 :(得分:2)

这可能是正常的。你的状态在相同的'tick'期间改变了两次(即:你的调度动作A1改变状态两次,一次直接来自处理你的动作的reducer,第二次是效果调度第二次动作)。

但改变检测只运行一次。所以你只能看到最后的变化。我想如果你的效果是后一次调度动作(可能是通过使用延迟操作符),你会看到OnChanges被调用两次。我很惊讶你看到S2-> S1改变而不是S1-> S1(它们具有相同的内容,但是因为状态是不可变的而是不同的对象),所以它可能不是正在发生的事情。

如果没有看到所有代码,很难看出这是不是正在发生的事情。你的效果是什么样的?是立即调度操作,还是执行某种AJAX请求,并在获得结果时调度操作?