- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到过这样的代码。问题是在选择已经在缓存中的项目后进度条没有消失(当缓存中的 api 调用使其工作正常时)。我能想到的是在 tap 中执行操作后没有运行变化检测。有人可以向我解释为什么吗?
@Component({
selector: 'app-item',
templateUrl: `
<app-progress-bar
[isDisplayed]="isProgressBar"
></app-progress-bar>
<app-item-content
[item]="item$ | async"
></app-item-content>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ItemComponent {
@Input()
set currentItemId(currentItemId: string) {
if (currentItemId) {
this.isProgressBar = true;
this.item$ = this.cache.get(currentItemId).pipe(
tap(() => {
this.isProgressBar = false;
//adding this.changeDetector.detectChanges(); here makes it work
})
);
} else {
this.isProgressBar = false;
this.item$ = of(null);
}
}
item$: Observable<ItemDto>;
isProgressBar = false;
constructor(
private cache: Cache,
private changeDetector: ChangeDetectorRef
) {}
}
缓存将项目存储在 private _data: Map<string, BehaviorSubject<ItemDto>>;
并过滤掉初始的 null emit
也在变化
<app-progress-bar
[isDisplayed]="isProgressBar"
></app-progress-bar>
到
<app-progress-bar
*ngIf="isProgressBar"
></app-progress-bar>
使其无需手动触发更改检测即可工作,为什么?
缓存:
export class Cache {
private data: Map<string, BehaviorSubject<ItemDto>>;
get(id: string): Observable<ItemDto> {
if (!this.data.has(id)) {
this.data.set(id, new BehaviorSubject<ItemDto>(null));
}
return this.data.get(id).asObservable().pipe(
tap(d => {
if (!d) {
this.load(id);
}
}),
filter(v => v !== null)
);
}
private load(id: string) {
this.api.get(id).take(1).subscribe(d => this.data.get(id).next(d));
}
编辑:
所以我想:tap 正在作为异步操作运行,这就是为什么它在更改检测已经在组件上运行后执行的原因。像这样:
但我摆弄了一下,做出了这样的东西:
templateUrl: `
<app-progress-bar
[isDisplayed]="isProgressBar$ | async"
></app-progress-bar>
<app-item-content
[item]="item$ | async"
></app-item-content>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ItemComponent {
@Input()
set currentItemId(currentItemId: string) {
if (currentItemId) {
this.itemService.setProgressBar(true);
this.item$ = this.cache.get(currentItemId).pipe(
tap(() => {
this.itemService.setProgressBar(false);
})
);
} else {
this.itemService.setProgressBar(false);
this.item$ = of(null);
}
}
item$: Observable<ItemDto>;
isProgressBar$ = this.itemService.isProgressBar$;
现在我不知道为什么在 tap() 中执行操作后更改检测没有在组件上运行,它与区域有关吗?
元素服务:
private progressBar = new Subject<boolean>();
setProgressBar(value: boolean) {
this.progressBar.next(value);
}
get isProgressBar$() {
return this.progressBar.asObservable();
}
最佳答案
对我来说,您的代码有两个主要问题:
您的缓存可能不会发出新值(我不知道是因为您没有提供它的实现),这意味着 async
管道不会被触发,
因为您检测到 onPush
,所以您的 View 没有被任何东西刷新:只有您触摸的方法/属性正在更新。 item$
与您的进度条无关,除非您使用 detectChanges
(它会触发组件更改检测),否则您看不到它正在更新。
关于 Angular 异步管道未触发 NgOnChange 的更改检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53665767/
NgChanges on 在输入绑定(bind)上运行 - 如果输入是引用类型 - 当引用发生变化时。即像这样的对象: { 值(value):2 如果它的值属性被改变,将不会导致 ngchanges
我正在尝试从组件的输入访问数据,并使用 ngOnChanges 这样做,但在控制台中抛出错误,如 "can not read property 'name' of undefined" but dat
在我的 angular 项目中,我试图通过点击下一个/上一个按钮来浏览列表。我有一个复选框,可以将显示的小时数从几小时更改为几天。我希望能够通过员工来回走动,并使值(value)观正确。有人告诉我,这
我有自动完成表单控件: @Component({ selector: 'app-autocomplete', templateUrl: './app-autocomplete.view
当我向数组添加项目时,ngOnChange 被触发: this.entries = [{"name": "John"},{"name": "Alex"},{"name": "Joe"}] 但当我删除这
我是 Angular 新手,只是关于 ngOnChanges 的问题。我知道 ngOnChanges() 方法需要一个参数(包含来自“@angular/core”的 SimpleChange),我们可
我有一个子组件,在其父组件中使用了两次,它使用 ngOnChaages 来更新值; 这一切都工作正常,但现在我正在尝试根据通过 @Input 变量传递的信息在子级中操作模板。 我发现的是;当父组件首次
我已经设置了 plunk 我在单击按钮时更改对象的 bool 属性,并且在单击 ngOnchange 时应该触发,但没有发生。为什么?。是否与父子组件之间共享相同的对象引用有关? 最佳答案 Angul
我正在使用 Angular 2 @Input 属性将所需的数值传递给子组件,就像这样。 父组件: @Component({ selector: 'test-parent', template: '
我遇到过这样的代码。问题是在选择已经在缓存中的项目后进度条没有消失(当缓存中的 api 调用使其工作正常时)。我能想到的是在 tap 中执行操作后没有运行变化检测。有人可以向我解释为什么吗? @Com
我需要检测 FormGroup 字段的实时变化。我有一个简单的父子组件结构如下: 父组件 View 子组件 Controller @Input() myForm: FormGroup; ngOnCh
我需要检测 FormGroup 字段的实时变化。我有一个简单的父子组件结构如下: 父组件 View 子组件 Controller @Input() myForm: FormGroup; ngOnCh
我正在开发这个 angular2 应用程序,其中我在一个组件中接受两个输入。 我使用 ngOnChanges 来检测这些输入值的变化。 @Input() games: any; @Input() se
所以基本上我有一个对象数组,我想通过 @Input 将数组中选定对象的索引提供给另一个组件。 问题是,当两次选择相同的项目时,ngOnChanges 函数没有检测到变化,因为当我将值从 1 设置为 1
我有一个包含复杂输入(一些图表数据)的子组件。在获得 API 响应后,我通过 Angular 5 中的 @Input() 装饰器从父组件发送此图表数据。因此,每次在父组件上发生更改时,我都需要根据 A
TL;DR:ngOnChanges 显示正在检测输入属性的更改,但未更新 View 我正在开发一个 Angular (2+) 应用程序,试图为使用 Observable 的服务完成的异步任务制作进度条
官方演示代码片段: ngOnChanges(changes: {[propKey: string]: SimpleChange}) {} 我的问题是ngOnChanges的参数。 changes是参数
在 Angular 2 中改变组件属性时,您能否以编程方式触发 Angular 变化检测? @Component({ selector: 'my-component', }) class MyC
比较 NgOnChanges 的最佳方法是什么,同时制作它 字符串类型安全 在 Angular ?目前这就是我正在做的。 NgOnChanges SimpleChanges 变量是数据类型:any 并
我是 Angular 5 的新手,我正在从它提供的官方网站学习组件交互 ngOnChanges(changes: {[propKey: string]: SimpleChange}) {} 并且在生命
我是一名优秀的程序员,十分优秀!