Skip to content

Commit 192576c

Browse files
ying.liuying.liu
authored andcommitted
revise angular best practices
1 parent e62bf20 commit 192576c

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

frontend/angular-best-practices.md

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ Simply, follow the following rules:
7171
- Use `ngOninit()` to initialize data-bound properties or subscribe to third-party widget events.
7272
- Use `ngDestroy()` to clear resources such as unsubscribing from observables.
7373

74-
Use the other hooks only if you fully understand the consequences:
74+
Use the other hooks only if you fully understand the consequences. Avoid the following three because they run in all possible UI and asynchronous events.
7575

7676
- Use `ngAfterViewInit()` when you need to do something after the component view is initialized. The `@ViewChild` fields are initialized when this hook is called.
77-
- Use `ngOnChanges()` if you want to track parent bound `@Input` properties.
78-
- Use `ngDoCheck()` if you want to track self-component peroperties and calculated properties. For example, `ngDoCheck() { this.time = Time.getCurrentTime() }`.
77+
- Use `ngDoCheck()` if you want to track self-component peroperties and calculated properties. For example, `ngDoCheck() { this.time = Time.getCurrentTime() }`. It ocurrs evey time there is a possible change event such as button clicked, promise completed or http response received. The method must be very quick because it happens a lot.
78+
- `ngAfterContentChecked()` occures after `ngDoCheck()` and when Angular finishes checking its projected contents -- triggered under the same condition as the `ngDoCheck()`. Should be careful when use this method. This is the last chance that you can change component view data after each change detection run because it happens before view is rendered. But you cann't change the projected contect properties becaue it happens after the content is checked. `ExpressionChangedAfterItHasBeenCheckedError` is throwed if content property is changed in or after the `ngAfterContentChecked()` hook.
7979

8080
## Forms
8181

@@ -109,12 +109,30 @@ createForm() {
109109
- Use file structure to scope services. A module can only use services that are in its subfoler or share the same parent folder.
110110
- Use `providers: []` for services that 1) need initialization (such as `myService.forRoot()`) or 2) inside `@Component` or `@Directive` for scoped mulitple-instance services.
111111

112-
## 异步操作和 Spin
112+
## RxJS 数据流和 Spin
113113

114-
RxJS 有二种常见的数据处理方式,用`subscribe()``pipe()`.
114+
在 UI 层,RxJS 有二种常见的数据获取方式,
115+
116+
- 用 HTML 里的`async`管道: `source$||async`
117+
- 用代码的`source$.subscribe(data=>...)`
118+
119+
### `async` 管道
120+
121+
用 HTML 里的`async`管道: `source$||async` 来获取数据是建议的异步数据获取方式。原因有二个:自动支持`ChangeDetectionStrategy.OnPush` strategy; 支持自动释放资源`unsubscribe()`。 当运行后台任务时需要显示 Spinner 或 loading 信息时,可以参考如下代码:
122+
123+
```ts
124+
this.startSpin()
125+
this.source$ = this.service
126+
.getData()
127+
.pipe(finalize(() => this.stopLoading())
128+
```
129+
130+
采用`finalize()`来在正常或错误情况下都停止显示 spinner 或 loacing 信息。此处的`finalize()``error``complete`之后调用。
131+
132+
### `Subscribe` 方式
115133
116134
```ts
117-
// 方式一: recommended
135+
// 方式一
118136
this.service.getData().subscribe(data => this.onSuccess(data), error => this.handleError(error))
119137

120138
// 方式二
@@ -127,11 +145,9 @@ this.service
127145
.subscribe()
128146
```
129147
130-
建议采用方式一的原因在最后一步分别处理正常和错误数据而不用顾虑处理结果, 避免了方式二为了保证统一输出所需要的`of()`转换。
131-
132-
建议`pipe()`只用于调试,log,延时,错误重试或需要数据转换但不能用`subscribe()`的场合。
148+
方式一在最后一步分别处理正常和错误数据而不用顾虑处理结果。方式二为了保证统一输出所需要用`of()`转换。
133149
134-
当运行后台任务时需要显示 Spinner 或 loading 信息。建议采用如下模式:
150+
`subscribe()`方式的弊端有二个:不支持`ChangeDetectionStrategy.OnPush` strategy; 有时候需要释放资源`unsubscribe()`。虽然不建议这种方法,但是为了有助于理解,下面给出当运行后台任务时需要显示 Spinner 或 loading 信息的例子。
135151
136152
```ts
137153
// recommended
@@ -142,7 +158,7 @@ this.service
142158
.add(() => this.stopSpin())
143159
```
144160
145-
采用`finalize()`来在正常或错误情况下都停止显示 spinner 或 loacing 信息。此处的`finalize()``error``complete`之后调用。其效果和如下二种方法一致:
161+
其效果和如下二种方法一致:
146162
147163
```ts
148164
//

0 commit comments

Comments
 (0)