本章节讲解 ngIf 指令
*ngIf 指令
用法一
<div *ngIf="条件表达式">
在条件为真的时候需要显示的内容
</div>
用法二
<div *ngIf="条件表达式 else elseContent">
在条件为真的时候需要显示的内容
</div>
<ng-template #elseContent>
在条件为假的时候需要显示的内容
</ng-template>
用法三
<div *ngIf="条件表达式;then thenTemplate; else elseTemplate">
</div>
<ng-template #thenTemplate>
在条件为真的时候需要显示的内容
</ng-template>
<ng-template #elseTemplate>
在条件为假的时候需要显示的内容
</ng-template>
用法三实际上是ngIf内部执行时的样子,代码书写时大部分情况下按用法一、二的方式使用
我们来看一下pinduoduo移动端页面,点击导航栏时,每个选中的选项下面是有一个下划线出现的,如下图:
组件的输入和输出
先从之前的代码上来理解一下何为父组件?何为子组件?
以app.component 和 scrollable-tab.component 为例。
父组件为app.component
子组件为scrollable-tab.component.
app.component.html
<app-scrollable-tab></app-scrollable-tab>
scrollable-tab 组件在根组件模板中被根组件使用,那么scrollable-tab 就是根组件的子组件,根组件即为父组件。在任何一个组件中,组件的调用方都是父组件,被调用组件为子组件。
接下来我们看一下关于封装的子组件scrollable-tab.component, 有哪些输入输出属性可以定义。
比如目前有一个非常大的问题就是我们把topMenus直接定义在了子组件scrollable-tab.component中了,如果我想重用这个子组件而且显示不同的内容,那么目前这样的封装方法是不可能重用这个子组件的。我们想要达到的效果是我可以在任何地方使用这个子组件,而且能根据我想要显示的内容来显示。这就要求我们必须在调用子组件的父组件中给子组件定义显示内容,而不是直接在子组件中直接写死显示内容。
在Angular中有两个装饰器来处理类似情况:@Input
,@Output
。专门用来实现跨组件通讯,双向绑定等操作所用的。
比如,我们在scrollable-tab.component中给topMenus添加@Input
装饰器,这就代表这个topMenus属性的值由外部输入进来的。
@Input() menus: TopBars[] = [];
把menus中的具体值定义在父组件中,并且以属性的形式在调用时给子组件赋值
<app-scrollable-tab [menus]="topBars"></app-scrollable-tab>
所以,当其它组件也有类似的菜单需要展示,那么就可以以同样的方式调用scrollable-tab子组件并且赋予其不同的显示类容。
另外,我们点击顶部菜单时,其实是要切换到不同页面去的。那么切换页面这个动作是子组件自己做好还是让其调用的父组件来做好呢?
当然是调用者来做比较合适,对于子组件来说,只知道要显示顶部菜单,但它并不知道父组件要导航到哪里去。也许每个调用者对导航的定义都不同,所以子组件不可能将这个行为封装在自己的组件中。但是,子组件知道目前点击了哪个菜单,对于子组件来说需要让父组件知道目前点了哪个菜单。
在子组件中定义一个函数handleSelection处理子组件中的选择事件,把选中的item作为参数,如下:
.html
<ul>
<li *ngFor="let item of menus; let i=index">
<a href="#" [class.active]="selectedIndex === i" (click)="hanleSelection(i)">{{item.title}}</a>
<span class="indicator" *ngIf="selectedIndex === i"></span>
</li>
</ul>
.ts
export class ScrollableTabComponent implements OnInit {
selectedIndex = -1;
constructor() { }
@Input() menus: TopBars[] = [];
@Output() tabSelected = new EventEmitter();
ngOnInit() {
}
hanleSelection(index: number) {
this.selectedIndex = index;
this.tabSelected.emit(this.menus[this.selectedIndex]);
}
}
EventEmitter
是事件发射器,先定义Output。然后在hanleSelection
方法中把目前选中的tab放到事件发射器中,这样就可以把选中的菜单传递给父组件。目前我们只在父组件中打印出选中的菜单,后续会讲到详细处理方法。
父组件中的适用
<app-scrollable-tab [menus]="topBars" (tabSelected)="handleTabSelected($event)"></app-scrollable-tab>
handleTabSelected(tabMenu: TopBars) {
console.log(tabMenu);
}
运行看一下效果