typescript - Hur man konstruerar en expanderbar rullgardinsmeny med angular2?
Jag vill bygga en expanderbar rullgardinsmeny med angular2. Vid onClick skulle rullgardinsmenyn expandera och vid onBlur skulle rullgardinsmenyn dra ihop sig.
Det enda sättet jag kan komma på för att uppnå detta beteende är att behålla en variabel som håller reda på tillståndet.
@Component({
selector: 'dropdown',
pipes: [SearchPipe],
template:
`
<div (blur)=updateState(false)>
<input [(ngModel)]="searchText" placeholder="name" (click)="updateState(true)>
<li *ngIf="my_state" *ngFor="#item of items | search: searchText">
<div>{{item.title}}</div>
</li>
</div>
`
})
export class Dropdown {
items = [{title: 'hello world'}, {title: 'hello 2'}, {title: 'foo bar'}];
searchText = '';
my_state = false;
updateState(show_flag) {
my_state = show_flag
}
}
Att behöva uppdatera tillstånd gör koden lite rörig, finns det ett bättre sätt att skapa en expanderbar rullgardinsmeny?
Svar #1
Jag tror inte att det finns ett bättre/enklare sätt att uppnå detta (Förhoppningsvis kommer någon att rätta mig :) ). Men du kan göra din variabel lokal för endast mallen och bli av med updateState()-metoden.
@Component({
selector: 'my-app',
template:`
<div>
<input (blur)="my_state =false" [(ngModel)]="searchText" placeholder="name" (click)="my_state = true">
<div *ngIf="my_state">
<li *ngFor="#item of items">{{item.title}}</li>
</div>
</div>
`
})
export class AppComponent {
items = [{title: 'hello world'}, {title: 'hello 2'}, {title: 'foo bar'}];
searchText = '';
}
Plunker som demonstrerar både ovanstående och nedanstående sätt
Ett alternativt sätt (inte nödvändigtvis ett bättre sätt) innebär att skapa en separat komponent för rullgardinsmenyn och ha en offentlig metod på den för att ändra menyns tillstånd (samma logik, bara kanske renare kod).
@Component({
selector:'dropdown',
template:`
<div *ngIf="isOpened">
<li *ngFor="#item of items">{{item.title}}</li>
</div>
`
})
class DropDown{
@Input('initial-state') isOpened;
@Input() items;
toggle(newState){
this.isOpened = newState !== undefined ? newState: !this.isOpened:
}
}
då från föräldrakomponenten:
<input (blur)="dropdown.toggle(false)" [(ngModel)]="searchText" (click)="dropdown.toggle(true)">
<dropdown #dropdown [initial-state]="true" [items]="items"></dropdown>
Du kan också ladda komponenten via DynamicComponentLoader för att undvika *ngIf. Men om något, kommer det att göra koden rörigare.
