关于Angular Component changeDetection策略设置成OnPush的一个单元测试局限性
局限性:如果Component的changeDetection的值为ChangeDetectionStrategy.OnPush而不是Default,那么fixture.detectChanges()只有在一个test spec里第一次调用才会生效。
这是Angular一个已知的bug:https://github.com/angular/angular/issues/12313
解决方案:
beforeEach(() => {TestBed.configureTestingModule({imports: [OutletModule],declarations: [TableComponent],providers: [{ provide: TableRendererService, useClass: MockTableRendererService },],}).overrideComponent(TableComponent, {set: { changeDetection: ChangeDetectionStrategy.Default },}).compileComponents();fixture = TestBed.createComponent(TableComponent);tableComponent = fixture.componentInstance;tableRendererService = TestBed.inject(TableRendererService);fixture.detectChanges();});
ChangeDetectionStrategy.OnPush实际是一个枚举值,在Angular官网里有介绍:
enum ChangeDetectionStrategy {OnPush: 0Default: 1
}
区别
- OnPush: 0
Use the CheckOnce strategy, meaning that automatic change detection is deactivated until reactivated by setting the strategy to Default (CheckAlways). Change detection can still be explicitly invoked. This strategy applies to all child directives and cannot be overridden.
注意:仍然可以显式触发。
- Default: 1
Use the default CheckAlways strategy, in which change detection is automatic until explicitly deactivated.
我们甚至可以更改某个Component的change detection频率。
Detach change detector to limit how often check occurs
The following example defines a component with a large list of read-only data that is expected to change constantly, many times per second. To improve performance, we want to check and update the list less often than the changes actually occur. To do that, we detach the component’s change detector and perform an explicit local check every five seconds.
class DataListProvider {// in a real application the returned data will be different every timeget data() {return [1, 2, 3, 4, 5];}
}@Component({selector: 'giant-list',template: `<li *ngFor="let d of dataProvider.data">Data {{d}}</li>`,
})
class GiantList {constructor(private ref: ChangeDetectorRef, public dataProvider: DataListProvider) {ref.detach();setInterval(() => {this.ref.detectChanges();}, 5000);}
}@Component({selector: 'app',providers: [DataListProvider],template: `<giant-list></giant-list>`,
})
class App {}
Angular应用 changeDetection模式的设置框架代码
根据关键字ChangeDetectionStrategy搜索即可。
const createInject = makeMetadataFactory('Inject', (token) => ({ token }));
const createInjectionToken = makeMetadataFactory('InjectionToken', (desc) => ({ _desc: desc, ɵprov: undefined }));
const createAttribute = makeMetadataFactory('Attribute', (attributeName) => ({ attributeName }));
const createContentChildren = makeMetadataFactory('ContentChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: false, descendants: false }, data)));
const createContentChild = makeMetadataFactory('ContentChild', (selector, data = {}) => (Object.assign({ selector, first: true, isViewQuery: false, descendants: true }, data)));
const createViewChildren = makeMetadataFactory('ViewChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: true, descendants: true }, data)));
const createViewChild = makeMetadataFactory('ViewChild', (selector, data) => (Object.assign({ selector, first: true, isViewQuery: true, descendants: true }, data)));
const createDirective = makeMetadataFactory('Directive', (dir = {}) => dir);
var ViewEncapsulation;
(function (ViewEncapsulation) {ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation || (ViewEncapsulation = {}));
var ChangeDetectionStrategy;
(function (ChangeDetectionStrategy) {ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
const createComponent = makeMetadataFactory('Component', (c = {}) => (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c)));
const createPipe = makeMetadataFactory('Pipe', (p) => (Object.assign({ pure: true }, p)));
const createInput = makeMetadataFactory('Input', (bindingPropertyName) => ({ bindingPropertyName }));
const createOutput = makeMetadataFactory('Output', (bindingPropertyName) => ({ bindingPropertyName }));
const createHostBinding = makeMetadataFactory('HostBinding', (hostPropertyName) => ({ hostPropertyName }));
const createHostListener = makeMetadataFactory('HostListener', (eventName, args) => ({ eventName, args }));
const createNgModule = makeMetadataFactory('NgModule', (ngModule) => ngModule);
const createInjectable = makeMetadataFactory('Injectable', (injectable = {}) => injectable);//告诉Angular,你正在使用自定义元素
const CUSTOM_ELEMENTS_SCHEMA = {name: 'custom-elements'
};
```![在这里插入图片描述](https://img-blog.csdnimg.cn/20210213110729716.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2kwNDI0MTY=,size_16,color_FFFFFF,t_70)
关于Angular Component changeDetection策略设置成OnPush的一个单元测试局限性相关推荐
- Angular Component的默认changeDetection策略
默认策略为:ChangeDetectionStrategy.Default: 实现代码: /*** Type of the Directive metadata.** @publicApi*/ con ...
- Angular Component UI单元测试的隔离策略
这是我需要进行单元测试的Component UI: 可以看到它依赖了另一个Component,其selector为cx-carousel. 因此我在单元测试实现文件里,给它创建一个mock Compo ...
- 深入解析Angular Component的源码示例
本篇文章主要介绍了剖析Angular Component的源码示例,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Web Component 定 ...
- 关于 Angular Component ngOnDestroy 钩子函数的调用时机
我开发了一个 Angular Component,实现了 ngOnDestroy 钩子方法之后,没有找到其被调用的方法.查看这个StackOverflow链接后,得知无论是我刷新浏览器,还是从当前页面 ...
- Angular Component代码和编译后生成的JavaScript代码
从 TypeScript 转换为 JavaScript 在这里称为编译. 在这种情况下,compiling 并不意味着创建二进制代码. 对于这种翻译,使用术语 transpilation 而不是 co ...
- SAP Spartacus维护CMS Component到Angular Component的源代码位置
Spartacus界面上的banner,如下图所示,对应着HTML源代码里的cx-banner标签: cx-banner下面是cx-generic-link: 这个cx-generic-link包含一 ...
- Angular component的职责
Angular Component的职责: Ideally, a component's job is to enable the user experience and nothing more. ...
- ft服务器设置传输协议,ft服务器设置成主动模式
ft服务器设置成主动模式 内容精选 换一换 如果您选择使用SFS Turbo实现文件共享存储,此章节操作可跳过,您可以参见<SAP HANA用户指南>中的"格式化磁盘" ...
- web字体设置成平方字体_探索免费和开放的Web字体
web字体设置成平方字体 毫无疑问,近年来,开源字体已经改变了网络的面貌. 在2010年之前,您可能会在网络浏览器中看到的唯一字体是Microsoft的通用"网络安全" 核心字体 ...
最新文章
- Oracle Gateway使用分享
- Java网络编程从入门到精通(4):DNS缓存
- java(9)并发编程
- WritableComparable排序案例(区内排序)
- 手把手教你用Java实现AOP
- 最短路 poj1125
- Java工作笔记-apache-tomcat-8.5.49及geoserver-2.7.5搭建
- 三款免费的PHP加速器:APC、eAccelerator、XCache比较
- 大一大学计算机课后答案,南昌大学计算机作业答案(大一)
- Python数据类型(3)
- 业务数据分析学习笔记--Lesson1
- 【UML】如何画好数据流图基础教程
- Appstore抓包获取APP历史版本
- 伟哥大数据入门教程一
- Android通知渠道
- drop,delete与truncate的区别
- 京东轮播图片的静态页面CSS3
- HttpRunner3使用
- Apache+php的安装和配置
- 郑刚答王峰十问:Telegram只是过渡性产品,区块链可能给社交产品带来让人兴奋的巨大改变...