0%

Angular-Tips

ngFor loop with async pipe

参数订阅可观察对象的值,从而保持最新,当数据更新时,循环渲染的视图会随之更新,见StackOverflow:*ngFor loop with async pipe?
完整栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component({
selector: 'users-list',
template: `
<ul>
<li *ngFor="let user of users$ | async">
{{ user.username }}
</li>
</ul>
`
})
export class UsersListComponent {
users$;

constructor(private http: Http) { }

ngOnInit() {
this.users$ = this.http
.get('/api/users')
.map(res => res.json());
}
}

如果需要基于返回值的其他参数,有
1
*ngFor="let user of users$ | async as users; index as i"

这里的users就是Array类型了
类似的ngIf也可以用异步管道,形如*ngIf=”user$ | async as user”,显然这里的user$应为Observable\

ngIf else

1
2
3
4
5
6
<div *ngIf="isLoggedIn(); else notLoggedIn">
Hi, {%raw%}{{ user.name }}!{%endraw%}
</div>
<ng-template #notLoggedIn>
You're not logged in.
</ng-template>

事件‘委托’

需求是文件上传,往往隐藏input type=”file”而放一个好看的入口。
事件可以直接在HTML的native element上触发,在jQuery中

1
$("#fileInput").click();

原生js
1
document.getElementById("fileInput").click();

Angular可以使用viewChild获取元素
1
2
3
4
5
6
7
8
@ViewChild('fileInput') fileInput:ElementRef;
constructor(private renderer:Renderer) {}

showImageBrowseDlg() {
let event = new MouseEvent('click', {bubbles: true});
this.renderer.invokeElementMethod(
this.fileInput.nativeElement, 'dispatchEvent', [event]);
}

MDN:dispatchEvent
通过dom结构定位元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div style="width: 128px; height: 128px; background-color: #fafafa;
border: 1px dashed #d9d9d9;
border-radius: 2px;cursor: pointer;display: flex;justify-content: center;align-items: center;"
(click)="showImageBrowseDlg($event)"> +
<input type="file" style="display: none;" (change)="handleUpload($event)">
</div>

showImageBrowseDlg(event){
if(event.target.children[0]){
const fileinput:HTMLElement = event.target.children[0] as HTMLElement;
fileinput.click();
event.stopPropagation();
}
}