为什么需要使用默认更改检测策略调用 detectChanges()?
Why do I need to call detectChanges() with the default change detection strategy?
我正在开发 Angular 4 应用程序,但我遇到了一个问题,因为我必须在模型更改时调用 this.changeDetectorRef.detectChanges();
来更新视图。例如,我有这个用于分页的代码:
changePage(pageNumber) {
this.currentPage = pageNumber;
// why do I need to do this?
this.changeDetectorRef.detectChanges();
}
我已将组件的更改检测策略明确设置为 ChangeDetectionStrategy.Default
但这没有任何效果。订阅可观察对象时也会发生这种情况:
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 }}
,它不会更新直到发生了一些其他事件,大概是在它经历另一个摘要周期时。
可能发生了什么?
==编辑========================================== =================
我的组件代码如下所示:
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
时,更改不会反映在 HTML 中,除非我调用 detectChanges()
。
您可以将您的 searchResults
输入到子组件中
@Input() searchResults;
之后通过父模板传递它
// parent template
<app-child [searchResults]="searchResults"></app-child>
您可以在子模板中使用它
// child template
<my-date-picker [ngModel]="searchResults"></my-date-picker>
之后您可以'listen'在子组件属性中对此进行更改
export class ChildComponent implements OnChanges {
@Input() searchResults;
constructor() { }
ngOnChanges() {
// some code
}
每次 searchResults
更改时,更改将填充到子组件中,子模板中的值将获得新值。
我已经解决了问题
向此组件发送通知的另一个组件 运行 Observable.fromEvent()
在 Angular 区域之外,因此更改检测不会自动发生以响应这些事件。 This post on zones and 对问题进行了解决!
我正在开发 Angular 4 应用程序,但我遇到了一个问题,因为我必须在模型更改时调用 this.changeDetectorRef.detectChanges();
来更新视图。例如,我有这个用于分页的代码:
changePage(pageNumber) {
this.currentPage = pageNumber;
// why do I need to do this?
this.changeDetectorRef.detectChanges();
}
我已将组件的更改检测策略明确设置为 ChangeDetectionStrategy.Default
但这没有任何效果。订阅可观察对象时也会发生这种情况:
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 }}
,它不会更新直到发生了一些其他事件,大概是在它经历另一个摘要周期时。
可能发生了什么?
==编辑========================================== =================
我的组件代码如下所示:
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
时,更改不会反映在 HTML 中,除非我调用 detectChanges()
。
您可以将您的 searchResults
输入到子组件中
@Input() searchResults;
之后通过父模板传递它
// parent template
<app-child [searchResults]="searchResults"></app-child>
您可以在子模板中使用它
// child template
<my-date-picker [ngModel]="searchResults"></my-date-picker>
之后您可以'listen'在子组件属性中对此进行更改
export class ChildComponent implements OnChanges {
@Input() searchResults;
constructor() { }
ngOnChanges() {
// some code
}
每次 searchResults
更改时,更改将填充到子组件中,子模板中的值将获得新值。
我已经解决了问题
向此组件发送通知的另一个组件 运行 Observable.fromEvent()
在 Angular 区域之外,因此更改检测不会自动发生以响应这些事件。 This post on zones and