Skip to content

Commit a197bb1

Browse files
authoredNov 11, 2022
feat(util:other:lazy): add attriburte property (#1548)
1 parent a408cbb commit a197bb1

File tree

2 files changed

+112
-18
lines changed

2 files changed

+112
-18
lines changed
 

‎packages/util/other/lazy.service.spec.ts

+24-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ describe('utils: lazy', () => {
5151
doc = TestBed.inject(DOCUMENT);
5252
});
5353

54+
it('should be load via LazyLoadItem', () => {
55+
const res: NzSafeAny = {};
56+
const content = 'var a = 1;';
57+
spyOn(doc, 'createElement').and.callFake(() => res);
58+
srv.load([{ path: '1.js', options: { innerContent: content } }]);
59+
expect(res.innerHTML).toBe(content);
60+
});
61+
5462
describe('Scripts', () => {
5563
it('should be load a js resource', done => {
5664
srv.change
@@ -66,7 +74,7 @@ describe('utils: lazy', () => {
6674
const res: NzSafeAny = {};
6775
const content = 'var a = 1;';
6876
spyOn(doc, 'createElement').and.callFake(() => res);
69-
srv.loadScript('/1.js', content);
77+
srv.loadScript('/1.js', { innerContent: content });
7078
expect(res.innerHTML).toBe(content);
7179
});
7280
});
@@ -80,7 +88,7 @@ describe('utils: lazy', () => {
8088
srv.load('/1.css');
8189
});
8290
it('should be load a less resource', done => {
83-
srv.loadStyle('/1.less', 'stylesheet/less').then(res => {
91+
srv.loadStyle('/1.less', { rel: 'stylesheet/less' }).then(res => {
8492
expect(res.status).toBe('ok');
8593
done();
8694
});
@@ -91,7 +99,7 @@ describe('utils: lazy', () => {
9199
};
92100
const content = 'var a = 1;';
93101
spyOn(doc, 'createElement').and.callFake(() => res);
94-
srv.loadStyle('/1.js', 'stylesheet/less', content);
102+
srv.loadStyle('/1.js', { rel: 'stylesheet/less', innerContent: content });
95103
expect(res.innerHTML).toBe(content);
96104
});
97105
});
@@ -128,4 +136,17 @@ describe('utils: lazy', () => {
128136
});
129137
srv.load('/3.js');
130138
});
139+
140+
describe('#attributes', () => {
141+
it('should be working', () => {
142+
const res: NzSafeAny = {
143+
setAttribute(key: string, value: string): void {
144+
res[key] = value;
145+
}
146+
};
147+
spyOn(doc, 'createElement').and.callFake(() => res);
148+
srv.loadScript('/1.js', { innerContent: '', attributes: { a: 'b' } });
149+
expect(res.a).toBe('b');
150+
});
151+
});
131152
});

‎packages/util/other/lazy.service.ts

+88-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,20 @@ export interface LazyResult {
1010
error?: NzSafeAny;
1111
}
1212

13+
export interface LazyLoadItem {
14+
path: string;
15+
options?: LazyLoadOptions;
16+
}
17+
18+
export interface LazyLoadOptions {
19+
innerContent?: string;
20+
attributes?: { [qualifiedName: string]: string };
21+
rel?: string;
22+
}
23+
1324
/**
25+
* `LazyService` delay loading JS or CSS files.
26+
*
1427
* 延迟加载资源(js 或 css)服务
1528
*/
1629
@Injectable({ providedIn: 'root' })
@@ -33,27 +46,59 @@ export class LazyService {
3346
this.cached = {};
3447
}
3548

36-
load(paths: string | string[]): Promise<LazyResult[]> {
49+
private attachAttributes(el: HTMLElement, attributes?: { [qualifiedName: string]: string }): void {
50+
if (attributes == null) return;
51+
52+
Object.entries(attributes).forEach(([key, value]) => {
53+
el.setAttribute(key, value);
54+
});
55+
}
56+
57+
/**
58+
* Load script or style files
59+
*/
60+
load(paths: string | LazyLoadItem | Array<string | LazyLoadItem>): Promise<LazyResult[]> {
3761
if (!Array.isArray(paths)) {
3862
paths = [paths];
3963
}
4064

4165
const promises: Array<Promise<LazyResult>> = [];
42-
paths.forEach(path => {
43-
if (path.endsWith('.js')) {
44-
promises.push(this.loadScript(path));
45-
} else {
46-
promises.push(this.loadStyle(path));
47-
}
48-
});
66+
paths
67+
.map(v => (typeof v !== 'object' ? ({ path: v } as LazyLoadItem) : v))
68+
.forEach(item => {
69+
if (item.path.endsWith('.js')) {
70+
promises.push(this.loadScript(item.path, item.options));
71+
} else {
72+
promises.push(this.loadStyle(item.path, item.options));
73+
}
74+
});
4975

5076
return Promise.all(promises).then(res => {
5177
this._notify.next(res);
5278
return Promise.resolve(res);
5379
});
5480
}
5581

56-
loadScript(path: string, innerContent?: string): Promise<LazyResult> {
82+
/**
83+
* @deprecated Will be removed in 15.0.0, Please use `loadScript(path, options)` instead
84+
*/
85+
loadScript(path: string, innerContent: string, attributes?: { [qualifiedName: string]: string }): Promise<LazyResult>;
86+
/**
87+
* Load a script file
88+
*/
89+
loadScript(path: string, options?: LazyLoadOptions): Promise<LazyResult>;
90+
loadScript(
91+
path: string,
92+
innerContent?: string | LazyLoadOptions,
93+
attributes?: { [qualifiedName: string]: string }
94+
): Promise<LazyResult> {
95+
const options: LazyLoadOptions =
96+
typeof innerContent === 'object'
97+
? innerContent
98+
: {
99+
innerContent,
100+
attributes
101+
};
57102
return new Promise(resolve => {
58103
if (this.list[path] === true) {
59104
resolve({ ...this.cached[path], status: 'loading' });
@@ -70,8 +115,9 @@ export class LazyService {
70115
const node = this.doc.createElement('script') as HTMLScriptElement;
71116
node.type = 'text/javascript';
72117
node.src = path;
73-
if (innerContent) {
74-
node.innerHTML = innerContent;
118+
this.attachAttributes(node, options.attributes);
119+
if (options.innerContent) {
120+
node.innerHTML = options.innerContent;
75121
}
76122
node.onload = () =>
77123
onSuccess({
@@ -88,7 +134,33 @@ export class LazyService {
88134
});
89135
}
90136

91-
loadStyle(path: string, rel: string = 'stylesheet', innerContent?: string): Promise<LazyResult> {
137+
/**
138+
* @deprecated Will be removed in 15.0.0, Please use `loadStyle(path, options)` instead
139+
*/
140+
loadStyle(
141+
path: string,
142+
rel: string,
143+
innerContent?: string,
144+
attributes?: { [qualifiedName: string]: string }
145+
): Promise<LazyResult>;
146+
/**
147+
* Load a style file
148+
*/
149+
loadStyle(path: string, options?: LazyLoadOptions): Promise<LazyResult>;
150+
loadStyle(
151+
path: string,
152+
rel?: string | LazyLoadOptions,
153+
innerContent?: string,
154+
attributes?: { [qualifiedName: string]: string }
155+
): Promise<LazyResult> {
156+
const options: LazyLoadOptions =
157+
typeof rel === 'object'
158+
? rel
159+
: {
160+
rel,
161+
innerContent,
162+
attributes
163+
};
92164
return new Promise(resolve => {
93165
if (this.list[path] === true) {
94166
resolve(this.cached[path]);
@@ -98,11 +170,12 @@ export class LazyService {
98170
this.list[path] = true;
99171

100172
const node = this.doc.createElement('link') as HTMLLinkElement;
101-
node.rel = rel;
173+
node.rel = options.rel ?? 'stylesheet';
102174
node.type = 'text/css';
103175
node.href = path;
104-
if (innerContent) {
105-
node.innerHTML = innerContent;
176+
this.attachAttributes(node, options.attributes);
177+
if (options.innerContent) {
178+
node.innerHTML = options.innerContent;
106179
}
107180
this.doc.getElementsByTagName('head')[0].appendChild(node);
108181
const item: LazyResult = {

0 commit comments

Comments
 (0)
Please sign in to comment.