Как создать раскрывающийся компонент в Angular 2?

Я хочу создать раскрывающееся меню, используя Angular 2, но я не так, как это сделать в Angular 2-м пути ".

Я мог бы создать раскрывающийся компонент, который будет использоваться следующим образом:

<dropdown>
    <li (click)="action('item 1')">Item 1</li>
    <li (click)="action('item 2')">Item 2</li>
</dropdown>

Это кажется приятным, но тогда метод action должен быть определен на компоненте, который содержит элементы <dropdown> и <li>, не получает стили, применяемые к стилям в компоненте <dropdown>, что является нечетным.

Другим вариантом является создание компонентов, которые используются следующим образом:

<dropdown>
    <dropdown-item (click)="action('item 1')">Item 1</dropdown-item>
    <dropdown-item (click)="action('item 2')">Item 2</dropdown-item>
<dropdown>

Это более подробная информация, компонент раскрывающегося элемента обрабатывает действие click, а стили элементов также определяются компонентом выпадающего элемента.

Есть ли более канонический способ сделать это в Angular 2?

Изменить: я не говорю о пользовательском элементе ввода для формы. Больше похоже на меню с параметрами или контекстное меню правой кнопки мыши.

Ответы

Ответ 1

Я бы сказал, что это зависит от того, что вы хотите сделать.

Если раскрывающееся меню является компонентом для формы, управляющей состоянием, я бы использовал двустороннюю привязку Angular2. Для этого я бы использовал два атрибута: входной, чтобы получить связанный объект, а выходной - для уведомления при изменении состояния.

Вот пример:

export class DropdownValue {
  value:string;
  label:string;

  constructor(value:string,label:string) {
    this.value = value;
    this.label = label;
  }
}

@Component({
  selector: 'dropdown',
  template: `
    <ul>
      <li *ngFor="let value of values" (click)="select(value.value)">{{value.label}}</li>
    </ul>
  `
})
export class DropdownComponent {
  @Input()
  values: DropdownValue[];

  @Input()
  value: string[];

  @Output()
  valueChange: EventEmitter;

  constructor(private elementRef:ElementRef) {
    this.valueChange = new EventEmitter();
  }

  select(value) {
    this.valueChange.emit(value);
  }
}

Это позволяет использовать его следующим образом:

<dropdown [values]="dropdownValues" [(value)]="value"></dropdown>

Вы можете создать раскрывающийся список внутри компонента, применить стили и управлять выборами внутри.

Edit

Вы можете заметить, что вы можете либо просто использовать пользовательское событие в своем компоненте, чтобы инициировать выбор выпадающего списка. Таким образом, компонент теперь будет примерно таким:

export class DropdownValue {
  value:string;
  label:string;

  constructor(value:string,label:string) {
    this.value = value;
    this.label = label;
  }
}

@Component({
  selector: 'dropdown',
  template: `
    <ul>
      <li *ngFor="let value of values" (click)="selectItem(value.value)">{{value.label}}</li>
    </ul>
  `
})
export class DropdownComponent {
  @Input()
  values: DropdownValue[];

  @Output()
  select: EventEmitter;

  constructor() {
    this.select = new EventEmitter();
  }

  selectItem(value) {
    this.select.emit(value);
  }
}

Затем вы можете использовать компонент следующим образом:

<dropdown [values]="dropdownValues" (select)="action($event.value)"></dropdown>

Обратите внимание, что метод action является одним из родительского компонента (а не выпадающего).

Ответ 2

Если вы хотите использовать выпадающие меню bootstrap, я рекомендую это для angular2:

ngx-dropdown