我正在学习angular,因此我对bootstrap
和ng-bootstrap
都不感兴趣,因为学习目的我想自己做所有事情。
我创建了一个简单的下拉菜单。我的目标是将它放在一个地方并在许多不同的组件中使用,但我想尽可能避免代码重复。
我有的是:
- 类文件
export class DropdownElement {
private _currentValue: string;
private _listContent: string[];
private _unrolled: boolean;
//constructor with getters/setter ommitted for brevity
}
- 在使用该下拉列表的组件中
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
private userTypeDropdown: DropdownElement;
constructor() {
this.userTypeDropdown = new DropdownElement('Select a type', [
{
name: 'Admin'
},
{
name: 'Guest'
}
], false);
}
private dropdownClicked(dropdownElement: DropdownElement): void {
dropdownElement.open = !dropdownElement.open;
}
private dropdownEntryClicked(dropdownEntry: string, dropdown: DropdownElement): void {
dropdown.currentValue = dropdownEntry;
}
private closeDropdown(event: Event, dropdown: DropdownElement): void {
dropdown.open = false;
}
}
- 内部模板文件
<div class="dropdown-box" (clickOutside)="closeDropdown($event, userTypeDropdown)">
<div class="dropdown-btn-box">
<button type="button" class="dropdown-btn-with-label"
(click)="dropdownBtnClicked(userTypeDropdown)">
{{userTypeDropdown.currentValue}}
</button>
<button type="button" class="caret-down-btn" (click)="dropdownClicked(userTypeDropdown)">
<i class="fas fa-caret-down"></i>
</button>
</div>
<ul class="dropdown-ul" *ngIf="userTypeDropdown.unrolled">
<li *ngFor="let listEntry of userTypeDropdown.listContent" class="dropdown-list-entry"
(click)="dropdownEntryClicked(listEntry, userTypeDropdown)">
{{listEntry.currentValue}}
</li>
</ul>
</div>
.scss
为简洁起见省略了文件
我想把它放在一个地方(以避免代码重复)并在不同的组件中使用。
我会怎么做。
我相信这正是 ng-bootstrap
所做的。他们从 bootstrap
中获取下拉列表,将其包装在一些逻辑中,使其成为一个指令,仅此而已。我认为这里的答案是作为指令或子组件实现的(但不确定 @Input
/@Output
是否是该目的的正确选择)。再次,正如我所说,我是初学者,所以我可能是错的,所以这个问题。
这里“将下拉定义保留在一个地方并在许多地方使用”的正确方法是什么?
最佳答案
您可以为所有这些可重用组件创建一个模块,例如下拉菜单、模式甚至 HTML 输入控件,这些控件可以将您的验证和功能封装在它们所拥有的基线功能之上。 您可以进一步将独立于框架的代码抽象成更多的类,然后只使用 Angular 进行查看。就像您将代码抽象到 Dropdown 元素类中一样,您可以拥有一个提供 View 的基本下拉组件,这是您使用应用程序用户实现的。您可以通过在单独的组件中取出下拉 View 来使其更易于重用,这样做将帮助您在需要下拉列表的所有此类用例中使用下拉元素。您只需为下拉元素提供初始化数据和初始值,就可以开始了。
DropDown 类和可重用组件
export class Dropdown { private _currentValue: string; private _listContent: string[]; private _unrolled: boolean; //constructor with getters/setter ommitted for brevity } @Component({ selector: 'drop-down', templateUrl: './drop-down.component.html', styleUrls: ['./drop-down.component.scss'] }) export class DropDownComponent extends Dropdown implements OnInit { // Input are a way to of communication from parent to child as parent feeds the child with input properties // you can have your setter here @Input('list-content') public listContent : Array<any>; @Input('current-value') currentValue: any; // Output events are just a way of child to parent communication @Output('on-select-item') onSelectItem : EventEmitter<any> = new EventEmitter(); constructor() {} public dropdownClicked(): void { this.open = !this.open; } public dropdownEntryClicked(dropdownEntry: string): void { this.currentValue = dropdownEntry; this.onSelectItem.emit(this.currentValue); } public closeDropdown(): void { this.open = false; } }
使用此 Dropdown 可重用组件的应用程序用户 考虑到您是初学者,让我们将它们放在同一模块中,以便 App-users 与 DropdownComponent 出现在同一模块中。 (稍后您可以将下拉列表移动到 SharedModule 并通过在包含 AppUsersComponent 的模块中导入 SharedModule 来使用它)
@Component({ selector: 'app-users', templateUrl: './users.component.html', styleUrls: ['./users.component.scss'] }) export class UsersComponent implements OnInit { public userTypeDropdown: Array<any>; public defaultUserType = { name: 'Guest'}; public selectedUserType: any; constructor() { this.userTypeDropdown = ['Select a type', { name: 'Admin' }, { name: 'Guest' } ]; } public onSelectUser (userTypeSelected : any) : void { this.selectedUserType = userTypeSelected; } }
下拉菜单模板将与您用于应用程序用户的模板相同,但有一些变化,即函数参数(因为我已经改变了一些)
App-user 组件的模板主要亮点
<drop-down [list-content]="userTypeDropdown"
[current-value]="defaultUserType"
(on-select-item)="onSelectUser(userTypeSelected)></drop-down>
希望这对您有所帮助!
关于html - 将自己的 ui 组件提取到一个地方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56742892/