Skip to content

Commit b59149f

Browse files
committed
feat(demo): add change detection content
1 parent 099a74d commit b59149f

File tree

8 files changed

+165
-0
lines changed

8 files changed

+165
-0
lines changed

projects/elements-demo/src/app/core/layout/navigation/navigation.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ const NAVIGATION = [
2121
label: 'Use cases',
2222
url: 'docs/use-cases'
2323
},
24+
{
25+
label: 'Change detection',
26+
url: 'docs/change-detection'
27+
},
2428
{
2529
label: 'API',
2630
url: 'docs/api'
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { NgModule } from '@angular/core';
2+
import { Routes, RouterModule } from '@angular/router';
3+
4+
import { ChangeDetectionComponent } from './change-detection.component';
5+
6+
const routes: Routes = [{ path: '', component: ChangeDetectionComponent }];
7+
8+
@NgModule({
9+
imports: [RouterModule.forChild(routes)],
10+
exports: [RouterModule]
11+
})
12+
export class ChangeDetectionRoutingModule {}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<div class="wrapper">
2+
<h1>Change detection</h1>
3+
<p>
4+
In this section we're going to curate and discuss various change detection
5+
related issues and lessons learned when using Angular Elements.
6+
</p>
7+
8+
<h2>
9+
RxJs stream runs in a wrong (parent / outer) zone.js [Angular Elements]
10+
</h2>
11+
<h3>Description</h3>
12+
<p>
13+
This issue happens when using <code>@angular/element</code> inside of a
14+
parent Angular application. The parent application and element will NOT run
15+
in the same zone. This will lead to problems with change detection inside of
16+
the element when the <code>rxjs</code> stream was triggered by the change of
17+
the <code>@Input() prop</code> originating in the parent application.
18+
</p>
19+
<p>
20+
The stream will run in parent zone (instead of element zone) so any async
21+
operation (like backend request or using
22+
<code>debounceTime()</code> operator) will not trigger change detection of
23+
the element so the stream data will not be rendered...
24+
</p>
25+
<h3>Solution</h3>
26+
<ol>
27+
<li>
28+
Do NOT use <code>zone.js</code> in your Angular element and trigger change
29+
detection manually
30+
</li>
31+
<li>
32+
Use single (parent) <code>NgZone</code> also for both the application and
33+
the element.
34+
<pre [highlight]="codeExampleShareNgZone"></pre>
35+
</li>
36+
<li>
37+
Use <code>import 'zone.js/dist/zone-patch-rxjs';</code> in your Angular
38+
element. This will fix it BUT if the parent application (or ANY other lib
39+
used by the parent application) already has this import then the one in
40+
the element will be ignored and hence not solving the problem.
41+
</li>
42+
</ol>
43+
<p>
44+
Check out detailed description of the
45+
<a href="https://github.com/angular/angular/issues/31870" target="_blank"
46+
>issue</a
47+
>
48+
and some of the proposed solutions...
49+
</p>
50+
</div>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
h2 {
2+
margin: 40px 0 10px 0;
3+
font-weight: bold;
4+
}
5+
6+
h3 {
7+
margin: 20px 0 5px 0;
8+
font-weight: bold;
9+
}
10+
11+
ol {
12+
margin: 0 0 20px 0;
13+
}
14+
15+
:host-context(.responsive-large) {
16+
.wrapper {
17+
width: 70%;
18+
}
19+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { HighlightModule } from 'ngx-highlightjs';
3+
import typescript from 'highlight.js/lib/languages/typescript';
4+
5+
import { SharedModule } from '../../../shared/shared.module';
6+
7+
import { ChangeDetectionComponent } from './change-detection.component';
8+
9+
describe('ChangeDetectionComponent', () => {
10+
let component: ChangeDetectionComponent;
11+
let fixture: ComponentFixture<ChangeDetectionComponent>;
12+
13+
beforeEach(async(() => {
14+
TestBed.configureTestingModule({
15+
imports: [
16+
HighlightModule.forRoot({
17+
languages: () => [{ name: 'typescript', func: typescript }]
18+
}),
19+
SharedModule
20+
],
21+
declarations: [ChangeDetectionComponent]
22+
}).compileComponents();
23+
}));
24+
25+
beforeEach(() => {
26+
fixture = TestBed.createComponent(ChangeDetectionComponent);
27+
component = fixture.componentInstance;
28+
fixture.detectChanges();
29+
});
30+
31+
it('should create', () => {
32+
expect(component).toBeTruthy();
33+
});
34+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Component, OnInit } from '@angular/core';
2+
3+
@Component({
4+
selector: 'demo-change-detection',
5+
templateUrl: './change-detection.component.html',
6+
styleUrls: ['./change-detection.component.scss']
7+
})
8+
export class ChangeDetectionComponent implements OnInit {
9+
codeExampleShareNgZone = CODE_EXAMPLE_SHARE_NG_ZONE;
10+
11+
constructor() {}
12+
13+
ngOnInit() {}
14+
}
15+
16+
export const CODE_EXAMPLE_SHARE_NG_ZONE = `// in parent app (app.module.ts)
17+
export class AppModule {
18+
constructor(private ngZone: NgZone) {
19+
(window as any).ngZone = this.ngZone // store ngZone reference on the window object
20+
}
21+
}
22+
23+
// in element (main.ts)
24+
platformBrowserDynamic()
25+
.bootstrapModule(AppModule, { ngZone: (window as any).ngZone }) // use parent ngZone
26+
`;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { NgModule } from '@angular/core';
2+
import { HighlightModule } from 'ngx-highlightjs';
3+
4+
import { SharedModule } from '../../../shared/shared.module';
5+
6+
import { ChangeDetectionRoutingModule } from './change-detection-routing.module';
7+
import { ChangeDetectionComponent } from './change-detection.component';
8+
9+
@NgModule({
10+
declarations: [ChangeDetectionComponent],
11+
imports: [HighlightModule, SharedModule, ChangeDetectionRoutingModule]
12+
})
13+
export class ChangeDetectionModule {}

projects/elements-demo/src/app/features/docs/docs-routing.module.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ const routes: Routes = [
3939
{
4040
path: 'faq',
4141
loadChildren: () => import('./faq/faq.module').then(m => m.FaqModule)
42+
},
43+
{
44+
path: 'change-detection',
45+
loadChildren: () =>
46+
import('./change-detection/change-detection.module').then(
47+
m => m.ChangeDetectionModule
48+
)
4249
}
4350
]
4451
}

0 commit comments

Comments
 (0)