[英]extend a angular component with ng-template
我使用 Kendo Ui 作為我最喜歡的 Angular 用戶界面框架。
<kendo-multiselect [data]="listItems" [(ngModel)]="value">
<ng-template kendoMultiSelectHeaderTemplate let-dataItem>
<strong (click)="toggleSelection()">Alle Auswählen</strong>
</ng-template>
</kendo-multiselect>
到目前為止一切順利,但我幾乎在我的每個多選下拉列表中都需要更多的 ng-template。 所以我的問題是,我可以創建一個指令,我可以直接在主機組件上使用它來創建 ng-template 和我需要的所有其他東西,或者這里是擴展現有組件子模板的最佳解決方案。
示例結果:
<kendo-multiselect my-multiselectHeader
[data]="listItems"
[(ngModel)]="value">
</kendo-multiselect>
解決方案似乎比我以前想象的要容易。
我創建了一個新的周圍指令,我可以在其中訪問
使用此解決方案,我可以訪問原始多選中的所有自然屬性,並且僅在 ng-content 的幫助下擴展我“需要”的功能
sq-multiselect-extension.html:
<ng-template kendoMultiSelectHeaderTemplate let-dataItem>
<strong (click)="toggleSelection()" class="m-2 link-cursor">Alle Auswählen</strong>
</ng-template>
<ng-content></ng-content>
sq-multiselect-extension.ts:
import { Component, OnInit, ViewChild, ContentChild } from '@angular/core';
import { HeaderTemplateDirective, MultiSelectComponent } from '@progress/kendo-angular-dropdowns'
@Component({
selector: 'sq-multiselect-extension',
templateUrl: './sq-multiselect-extension.html',
})
export class SxpMultiselectComponent implements OnInit {
@ViewChild(HeaderTemplateDirective) headerTemplate: HeaderTemplateDirective;
@ContentChild(MultiSelectComponent) multiselect: MultiSelectComponent;
public ngOnInit() {
this.multiselect.headerTemplate = this.headerTemplate;
}
public toggleSelection(): void {
if (this.multiselect.value.length > 0) {
this.multiselect.reset();
}
else {
this.multiselect.writeValue(this.multiselect.data)
this.multiselect.value = this.multiselect.data.slice();
}
}
}
並使用這個新組件
<sq-multiselect-extension>
<kendo-multiselect [data]="listStringItems" [(ngModel)]="value" class="form-control">
</kendo-multiselect>
</sq-multiselect-extension>
是的,我認為這沒什么大不了的。 這僅取決於您想要做什么,但創建一個自定義標題的指令似乎並不難。
我認為您可以使用ng-template
注入和/或使用ngTemplateOutlet
。
但我建議您查看kendoMultiSelectHeaderTemplate
指令以檢查它的准確功能。
如果您使用的是let-dataItem
變量,請檢查您是否可以在自定義Directive
上使用它。
如果您打算重用多選輸入,我建議將 kendo 元素包裝到一個單獨的組件中。 這樣,如果您需要將一些自定義選項傳遞給 kendo 元素,您可以在一個地方完成,它會影響所有多選。
添加到steamwuschel的答案中,這對使用Angular 8
我來說是完美的
我已經使用Select All
功能擴展了 Kendo MultiSelect 組件
在ngOnInit
,組件尚未呈現,因此您將其視為未定義。 所以你必須使用AfterViewInit
multiselect-extended.component.ts
import {
Component,
OnInit,
ViewChild,
Output,
ContentChild,
AfterViewInit,
EventEmitter
} from "@angular/core";
import {
HeaderTemplateDirective,
MultiSelectComponent
} from "@progress/kendo-angular-dropdowns";
@Component({
selector: "app-custom-multselect",
templateUrl: "./custom-multselect.component.html",
styleUrls: ["./custom-multselect.component.css"]
})
export class CustomMultselectComponent implements OnInit, AfterViewInit {
@ViewChild(HeaderTemplateDirective, { static: false })
headerTemplate: HeaderTemplateDirective;
@ContentChild(MultiSelectComponent, { static: false })
multiselect: MultiSelectComponent;
@Output() selectAllEvent: EventEmitter<boolean> = new EventEmitter();
constructor() {}
ngOnInit() {}
ngAfterViewInit() {
console.log(this.multiselect);
this.multiselect.headerTemplate = this.headerTemplate;
}
public toggleSelection(): void {
if (this.multiselect.value.length > 0) {
this.multiselect.reset();
this.selectAllEvent.emit(false);
} else {
this.multiselect.writeValue(this.multiselect.data);
this.multiselect.value = this.multiselect.data.slice();
this.selectAllEvent.emit(true);
}
}
}
請注意,我添加了一個selectAllEvent
來更新多選下拉列表中顯示的復選框。
應用程序組件.html
<app-custom-multselect (selectAllEvent)=" selectAllItems($event)">
<kendo-multiselect [data]="listItems" [(ngModel)]="value" [textField]="'text'" [valueField]="'value'"
[autoClose]="false">
<ng-template kendoMultiSelectItemTemplate let-dataItem>
<input type="checkbox" class="k-checkbox"
[checked]="isItemSelected(dataItem.text) || isAllSelected">
<label class="k-checkbox-label">{{ dataItem.text }}</label>
</ng-template>
</kendo-multiselect>
</app-custom-multselect>
app.component.ts
export class AppComponent {
public listItems: Array<{ text: string; value: number }> = [
{ text: "Small", value: 1 },
{ text: "Medium", value: 2 },
{ text: "Large", value: 3 },
{ text: "XL", value: 4 },
{ text: "XXL", value: 5 }
];
public value: any = [];
public isAllSelected: boolean = false;
public isItemSelected(itemText: string): boolean {
return this.value.some(item => item.text === itemText);
}
selectAllItems(isSelectAll) {
if (isSelectAll) {
this.isAllSelected = true;
} else {
this.isAllSelected = false;
}
}
}
你也可以在StackBlitz上找到演示
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.