Как я могу создать пользовательскую директиву angular для отображения и скрытия дочернего элемента при нажатии на соседний элемент? - PullRequest
1 голос
/ 26 апреля 2020

Как создать пользовательскую директиву angular для отображения и скрытия дочернего элемента при щелчке по соседнему элементу?

Поэтому при нажатии на h2 я хочу отобразить custom_elem с помощью пользовательских директив.

Помните, что div повторяется с ngFor. Поэтому экземпляр div должен показывать дочерний элемент (custom_elem) только при нажатии на h2, в то время как дочерний элемент (custom_elem) других экземпляров div остается скрытым.

<div *ngFor="let item of items"> 
 <h2 (click)="" >item.name</h2>   // if I click here it will pass show or hide (true or false) values to the directive. 
 <custom_elem>somedata</custom_elem>  //show these (then the directive will handle the display properties of these child elements)
<div>

видите, что я этого не делаю; хочу динамически добавлять что-то новое.

ngfor уже зацикливается (в начале). Единственное, что мне нужно, это то, что я просто хочу переключать отображение (custom_elem), когда я нажимаю на h2 (используя пользовательскую директиву).

Нам нужна пользовательская директива. так что, когда я нажимаю на h2, я могу передать значения true или false директиве, а затем директива будет обрабатывать свойства отображения (custom_elem)

таким образом, свойства show или hide привязываются локально с экземпляром соответствующего элемента. & не подключен к component.ts.

UPDATE div повторяется с ngFor. h2 будет всегда виден. при нажатии на h2 дисплей custom_element включается и выключается.

Это конечный результат, необходимый. Когда я нажимаю на h2, я хочу отобразить соответствующий custom_elem (который является соседом h2).

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

это не похоже на то, что требует от меня специальной директивы:

<div *ngFor="let item of items"> 
 <h2 (click)="item.showData = !item.showData" >item.name</h2>
 <custom_elem *ngIf="item.showData">somedata</custom_elem> 
<div>

приведенный выше простой фрагмент кода, использующий директивы stock, кажется, соответствует требованиям ... если ваша цель - манипулировать видимость вместо добавления / удаления, вы могли бы просто использовать ngClass вместо этого с классом для применения необходимых стилей ... есть ли конкретная c причина, по которой вы предпочитаете что-то более нестандартное, чем это? Обычно я поддерживаю dry директивы многократного использования, но в данном случае это кажется излишним.

Стандартные передовые методы работы с клиентами - это то, что ваша модель данных и модель представления связаны, но разные вещи. Каждая модель данных должна быть представлена ​​в представлении, а модель данных почти никогда не бывает достаточной для моделирования представления, так как представление имеет такие вещи, как переключение скрытия / отображения или отображение значений, с которыми модель данных не связана. это нормально и ожидаемо.

, если у вас был интерфейс для вашей модели данных, такой как:

interface MyItem {
  id: number;
  user: {
    firstName: string,
    lastName: string
  };
  data: any;
}

, и вы хотите показать полное имя и переключатель открытия / закрытия, возможно, элемент может даже находиться в выбранном состоянии, вам нужно расширить эту модель, так как этого недостаточно для данного представления этих данных.

interface MyItemVm extends Item {
  displayName: string;
  selected: boolean;
  showData: boolean;
}

, и вы построите модель представления с функцией что-то вроде:

this.itemVm = items.map(i => ({
  ...i, 
  ...{displayName: `${i.user.firstName} ${i.user.lastName}`, selected: false, showData: false }
}));

теперь ваши данные правильно смоделированы для представления и легко переведены в шаблон с полезными свойствами для представления.

1 голос
/ 27 апреля 2020

Ну, это будет работать как отправная точка, но вам придется позаботиться о тех нескольких особых случаях, которые произойдут:

  1. Добавление / удаление элементов
  2. заголовок без дочерних элементов
  3. Позволяет указать тип элемента заголовка

По сути, на этом * 1011 показана начальная версия без оптимизации того, что вы запрашиваете. * Stackblitz demo (потому что здесь слишком много строк кода, чтобы разместить его здесь - но я постараюсь выделить некоторые моменты).

директива названа в честь appHideChildren, и ее можно использовать например:

<hello [appHideChildren]="true"></hello>

При этом все дочерние элементы компонента hello, кроме элементов h2, будут скрыты (поскольку для него установлено значение true). Это просто начальное состояние детей. После инициализации компонента щелчки по заголовкам позаботятся о переключении дисплея.

Что было сделано, так это найти все прямые дочерние элементы хост-компонента:

<!-- $el is the host element -->
this._children = $el.querySelectorAll(`${$el.tagName}>*`);

Затем к заголовкам добавляются прослушиватели событий (элементы h2), и обнаруживаются следующие элементы каждого заголовка и сохраняется ссылка на них. Слушатель событий перебирает все дочерние элементы заголовка, по которому щелкают, и переключает его статус. Предыдущее состояние свойства display сохраняется для восстановления при отображении компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...