为什么我需要使用默认的更改检测策略来调用detectChanges()? [英] Why do I need to call detectChanges() with the default change detection strategy?

查看:218
本文介绍了为什么我需要使用默认的更改检测策略来调用detectChanges()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 4应用程序,但是由于模型更改时必须调用this.changeDetectorRef.detectChanges();来更新视图,所以我遇到了问题.例如,我有以下用于分页的代码:

I am working on an Angular 4 app, but I am having a problem inasmuch as I am having to call this.changeDetectorRef.detectChanges(); to update the view when the model changes. For example, I have this code which is for pagination:

changePage(pageNumber) {
  this.currentPage = pageNumber;
  // why do I need to do this?
  this.changeDetectorRef.detectChanges();
}

我已将组件上的更改检测策略明确设置为ChangeDetectionStrategy.Default,但这没有效果.订阅可观察项时,它也在这里发生:

I have expicitly set the change detection strategy on the component to ChangeDetectionStrategy.Default but this has no effect. It is happening here too when subscribing to an observable:

showResults(preference) {
  this.apiService.get('dining_autocomplete/', `?search=${preference}`)
    .subscribe((results) => {
      this.searchResults = results;
      // why do I need to do this?
      this.changeDetectorRef.detectChanges();
  });
}

如果我在TypeScript中使用console.log() this.searchResults,则可以得到预期的结果,但是如果我在HTML中使用{{ searchResults }},则它不会更新,直到发生其他事件为止,大概是当它经过另一个摘要时循环.

If I console.log() this.searchResults in the TypeScript, I get the expected results, but if I use {{ searchResults }} in the HTML, it doesn't update until some other event happens, presumably when it goes through another digest cycle.

可能会发生什么?

==编辑============================================ ===============

== EDIT ===========================================================

我组件的代码如下:

import {ChangeDetectorRef, Component, Input, OnChanges} from "@angular/core";

import * as _ from 'lodash';

@Component({
  selector: 'dining-search-results',
  templateUrl: './dining-search-results.template.html',
  styleUrls: ['./dining-search-results.style.scss'],

})
export class DiningSearchResultsComponent {
  @Input() searchResults: any[];
  @Input() hotTablesOnly: boolean = false;
  @Input() memberBenefitsOnly: boolean = false;

  numberOfTagsToDisplay: number = 3;
  resultsPerPage: number = 5;
  currentPage: number = 1;

  constructor(private changeDetectorRef: ChangeDetectorRef) {
  }

  get filteredResults() {
    return this.searchResults ?
      this.searchResults.filter((r) => !((this.hotTablesOnly && !r.has_hot_table)
        || (this.memberBenefitsOnly && !r.has_member_benefit))) : [];
  }

  get pagedResults() {
    return _.chain(this.filteredResults)
      .drop(this.resultsPerPage * (this.currentPage - 1))
      .take(this.resultsPerPage)
      .value();
  }

  get totalPages(): number {
    return Math.ceil(this.filteredResults.length / this.resultsPerPage);
  }

  getInitialTags(tagsArray: any[], count: number): any[] {
    return _.take(tagsArray, count);
  }

  changePage(pageNumber) {
    this.currentPage = pageNumber;
    // why do I need to do this?
    this.changeDetectorRef.detectChanges();
  }
}

调用changePage()并更新this.currentPage时,除非我调用detectChanges(),否则更改不会反映在HTML中.

When changePage() is called, and this.currentPage is updated, the changes are not reflected in the HTML unless I call detectChanges().

推荐答案

我已经解决了问题.

向该组件发送通知的另一个组件在Angular区域之外正在运行Observable.fromEvent(),因此响应这些事件不会自动进行更改检测. 有关区域的帖子有关此问题的StackOverflow帖子提出了解决方案!

Another component sending notifications to this component was running Observable.fromEvent() outside the Angular zone, so change detection was not happening automatically in response to these events. This post on zones and this StackOverflow post on the issue held the solution!

这篇关于为什么我需要使用默认的更改检测策略来调用detectChanges()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆