将自己的用户界面组件提取到一个地方

时间:2019-06-24 19:35:11

标签: html css angular

我正在学习有角度的知识,因此我对bootstrapng-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是用于此目的的正确选择)。再次,正如我所说,我是一个初学者,所以我可能错了,因此是个问题。

这里“将下拉列表定义保留在一个地方并在许多地方使用”的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以在文件selector的{​​{1}}中使用component.ts将组件插入其他组件,也可以在app-user的其他component.html模板中使用

在询问您有关将数据传递到组件的评论中,这是示例:

孩子hello.component.ts:

<app-users></app-users>

父亲hello-list.component.html:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-hello',
  template: '<p>Hello, {{name}}!</p>',
})
export class HelloComponent {
  @Input() name: string;
}

记住要下载<div *ngFor="let hello of hellos" <app-hello [name]='hello'></app-hello> </div> 文件中的列表

答案 1 :(得分:1)

您可以为所有这些可重用的组件(例如下拉菜单,模式,甚至HTML输入控件)创建一个模块,这些模块可以在其所拥有的基线功能之上封装您的验证和功能。 您可以将框架无关的代码进一步抽象为其他类,而只需使用Angular进行查看。就像您将代码抽象到Dropdown元素类中一样,您可以具有一个基本的dropdown组件,该组件提供使用应用程序用户实现的视图。您还可以通过在单独的组件中删除下拉列表视图来使其更可重用,这将有助于您在需要下拉列表的所有此类用例中使用dropdown元素。您只需向下拉元素提供初始化数据和初始值,就可以了。

  • 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用户与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;
      }
    }
    
  • 用于下拉菜单的模板将与您用于应用程序用户的模板相同,只是进行了一些更改,例如函数参数(因为我做了一些更改)

  • 应用程序用户组件的模板 主要亮点

<drop-down [list-content]="userTypeDropdown"
[current-value]="defaultUserType"
(on-select-item)="onSelectUser(userTypeSelected)></drop-down>

希望这会有所帮助!