- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在过去几年从事 React 项目之后,我才开始接触 Angular。
我有一个使用 changeDetection: ChangeDetectionStrategy.OnPush
的组件,但我不喜欢我的解决方案。问题是我发现很难找到 ChangeDetectionStrategy.OnPush
例如,我有一个组件有点像这样:
files: Uploads[] = [];
get canUpload() {
return this.files.length > 0l
}
get isUploading() {
return this.files.length > 0 && this.files.some((f) => f.state === FileUpLoadState.uploading);
}
get activeFiles() {
return this.files.filter((f) => f.state !== FileUpLoadState.success);
}
uploadFiles() {
if (!this.files.length) {
return;
}
const fileList: FileList = (event.target as HTMLInputElement).files;
for (const uploadedFile of Array.prototype.slice.call(fileList)) {
// do stuff
this.files.push(new Upload(file));
}
}
我有像这样在模板中使用的这些属性;
<button (click)="uploadFiles()" [disabled]="!this.canUpload">Upload</button>
我真的不喜欢这样,使用默认的更改检测不会扩展,而且何时传播更改不在我的控制范围内。
如何重构此代码以使用 OnPush 更改检测?
最佳答案
人们回答你,但他们不会解释你。
OnPush
策略是变更检测中最有效的策略。 Angular 默认不实现它,因为新手习惯于看到魔法(即当您开始使用 Angular 时,默认策略对错误更友好且更容易理解)。
为了检测变化,Angular 会监听您 View 上的事件。使用默认策略,可能会导致大量无用的更改检测。
在推送策略中,您可以控制何时触发更改检测。
在这两种情况下,Angular 都使用内存引用来了解数据何时更新。这就是对象不可变性在 Angular 中如此重要的原因,也是响应式(Reactive)编程如此有效的原因。
话虽这么说,如果你想切换到推送策略,你应该使用以下内容:
// files: Uploads[] = [];
files: BehaviorSubject<Uploads[]> = new BehaviorSubject([]);
add(item) {
this.files.pipe(first()).subscribe(files => this.files.next([...files, item]));
}
get canUpload() {
// return this.files.length > 0l
return this.files.pipe(
map(files => files.length),
map(size => !!size)
);
}
get isUploading() {
// return this.files.length > 0 && this.files.some((f) => f.state === FileUpLoadState.uploading);
return this.files.pipe(
startWith(false),
filter(files => !!files.length),
filter(files => files.some(f => f.state === FileUpLoadState.uploading)),
map(() => true)
);
}
get activeFiles() {
// return this.files.filter((f) => f.state !== FileUpLoadState.success);
return this.files.pipe(
map(files => files.filter(f => f.state !== FileUpLoadState.success)),
);
}
uploadFiles() {
/*
if (!this.files.length) {
return;
}
const fileList: FileList = (event.target as HTMLInputElement).files;
for (const uploadedFile of Array.prototype.slice.call(fileList)) {
// do stuff
this.files.push(new Upload(file));
}
*/
this.files.pipe(
filter(files => !!files.length),
map(files => (event.target as HTMLInputElement).files),
first()
).subscribe(files => {
for (const uploadedFile of Array.prototype.slice.call(fileList)) {
// do stuff
this.add(new Upload(file));
}
});
}
这是您可以执行的众多实现之一。我不确定这是否会按您期望的方式工作,我只是“翻译”了代码,因此您可能需要进行一两次调整。
这样,当您的收藏发生变化时,您的 View 会自动更新。您无需执行任何操作。这符合推送策略,因为响应式编程会触发变更检测。
并且因为每个 getter 都依赖于您的 BehaviorSubject,所以它们都会在该主题的每次更改时更新。
只是一个“缺点”(实际上不是),就是在您的组件模板中,您必须使用异步管道:
<ng-container *ngIf="canUpload | async">...</ng-container>
如果您有任何问题,请随时提出!
关于angular - 将代码从 ChangeDetectionStrategy.Default 重构为 ChangeDetectionStrategy.OnPush,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54637334/
在过去几年从事 React 项目之后,我才开始接触 Angular。 我有一个使用 changeDetection: ChangeDetectionStrategy.OnPush 的组件,但我不喜欢我
我不明白为什么子组件的更改检测会在这种情况下运行: import { Component, ChangeDetectionStrategy } from '@angular/core' @Compon
我不明白为什么子组件的更改检测会在这种情况下运行: import { Component, ChangeDetectionStrategy } from '@angular/core' @Compon
我正在尝试熟悉 Angular 2 的 ChangeDetectionStrategy.OnPush 性能提升(如 here 所述)。但我这里有古玩盒。 我有父 AppComponent: @Comp
我正在构建一个包含许多组件的 Angular 4 应用程序,其中 ChangeDetectionStrategy 是 OnPush。同时the Angular Documentation on the
我是否应该始终在我的组件中使用 ChangeDetectionStrategy.OnPush? 我总是听说 OnPush 非常棒,它解决了很多问题,加快了 Angular 应用程序的速度,甚至摆脱了
我有一个使用服务提交一些数据的组件。 该组件使用 ChangeDetectionStrategy.OnPush ,但发生了一些奇怪的事情: 当请求 成功 : next回调被调用,formStatus更
正如标题所说:我正在处理一个非常大的项目,而且我使用过的组件很少 ChangeDetectionStrategy.OnPush以免表现不佳。我想知道,将策略的每个组件都放入“好”,以防万一,使用 Ch
https://stackblitz.com/edit/angular-xpamld 问题:有人能帮我理解为什么我的原型(prototype)的 changeDetection: ChangeDete
如何将 ChangeDetectionStrategy.OnPush 设置为每个的默认策略我的应用程序中的组件,而不是在每个组件的模板上编写changeDetection: ChangeDetecti
我试图了解 ChangeDetectionStrategy.OnPush机制。 我从我的读数中收集到的是,通过将旧值与新值进行比较来进行更改检测。如果对象引用未更改,则该比较将返回 false。 但是
我有这个简单的组件。 @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-spinner'
在我的 Angular 应用程序中,我通过实现 ControlValueAccessor 创建了一个自定义表单元素。界面。 因此,在我的组件中,我正确实现了该接口(interface)的所有方法,包括
我有 Angular 分量 l @Component({ selector: 'aas-add-option', templateUrl: './add-option-modal.compon
假设我有一个这样的组件结构: AppComponent HeaderComponent ContentComponent TodosComponent
我正在使用可观察对象将服务列表返回到我的组件,在我的组件中我使用 ChangeDetectionStrategy.OnPush,在模板中我使用异步管道,希望这会带来一些性能优势,因为未执行更改检测所有
我转载了一个简单的stackblitz证明我一直遇到的问题。问题是我有一个将 bool 值传递给子组件的父组件。这个 bool 值是子组件上的@Input。需要注意的是,父组件使用 ChangeDet
我有一个容器组件,其中注入(inject)了一个服务。该服务包含一个可观察的。在容器组件的模板中,我使用异步管道将该可观察对象绑定(bind)到子组件的输入属性。一切似乎都正常,除了我必须与 UI 交
我有两个组件,我在其中使用 ChangeDetectionStrategy.OnPush。父组件: @Component({ changeStaregy: ChangeDetecti
我正在使用 OnPush 策略并根据此 article如果没有输入更改,则无需检查组件的模板。但在我的示例中,当我单击触发按钮并且输入没有更改时,在这种情况下 ngAfterViewChecked H
我是一名优秀的程序员,十分优秀!