Событие Angular click: как установить флажок внутри элемента?

В моем приложении Angular у меня есть следующее меню:

введите здесь описание изображения

Как вы можете видеть, у меня есть элементы (которые являются a элементами), а также флажок и метка в каждом из них:

<span class="caption">RAM</span>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>4 GB</label>
    </div>
</a>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>8 GB</label>
    </div>
</a>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>16 GB</label>
    </div>
</a>

Как мне добавить (click) к каждому элементу, чтобы правильно обрабатывать захват событий, поэтому, если пользователь нажимает на метку или на весь элемент, я получаю соответствующий флажок?

...Или вы знаете лучший способ понять, что я имею в виду?


person smartmouse    schedule 16.01.2020    source источник


Ответы (5)


Чтобы убедиться, что щелчок по метке переключает флажок, включите элемент ввода внутрь метки (как описано в MDN):

<a class="sub-item item">
  <div class="item-checkbox">
    <label><input type="checkbox" tabindex="0" class="hidden">4 GB</label>
  </div>
</a>

Если вы также хотите, чтобы метка заполнила элемент привязки, определите CSS, как показано ниже. С этим стилем нажатие на якорь приведет к переключению флажка.

.ui.secondary.menu a.item {
  padding: 0px;
}

div.item-checkbox {
  width: 100%;
  height: 100%;
}

div.item-checkbox > label {
  display: block;
  padding: .78571429em .92857143em;
}

div.item-checkbox > label > input {
  margin-right: 0.25rem;
}

См. этот stackblitz для демонстрации.

person ConnorsFan    schedule 16.01.2020
comment
Это выглядит лучшим ответом. В любом случае, как расширить щелчок до элемента a? Таким образом, нажатие на a установит флажок. Пожалуйста, взгляните на мой stackblitz: stackblitz.com/edit/semantic-ui-udkfhf. Спасибо - person smartmouse; 17.01.2020
comment
Я обновил ответ и stackblitz, чтобы убедиться, что нажатие на привязку переключает флажок. - person ConnorsFan; 17.01.2020

Если вы можете разместить все флажки в контейнере, вы можете установить один прослушиватель событий click в контейнере, и event.target даст вам элемент, по которому щелкнули, а previousElementSibling выберет одноуровневый ввод.

function doSomething() {
    const selectedInput = event.target.previousElementSibling;
    selectedInput.checked = selectedInput.checked? false : true;
}

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

document.getElementById('container').addEventListener('click', doSomething);

function doSomething() {
    const selectedElement = event.target.parentElement.querySelector('input[type="checkbox"]');
    selectedElement.checked = selectedElement.checked? false:true;
}
<div id= 'container'>
  <span class="caption">RAM</span>
  <a class="item">
      <div class="item-checkbox">
          <input type="checkbox" tabindex="0" class="hidden" value="4 GB">
          <label>4 GB</label>
      </div>
  </a>
  <a class="item">
      <div class="item-checkbox">
          <input type="checkbox" tabindex="0" class="hidden" value="8 GB">
          <label>8 GB</label>
      </div>
  </a>
  <a class="item">
      <div class="item-checkbox">
          <input type="checkbox" tabindex="0" class="hidden" value="16 GB">
          <label>16 GB</label>
      </div>
  </a>
</div>

person Addis    schedule 16.01.2020
comment
Я не ясно выразился, извините за это. Я говорю о захвате событий. Я отредактировал свой вопрос. В вашем фрагменте, если вы нажмете на метку или на весь элемент, я не выберу соответствующий флажок. - person smartmouse; 16.01.2020

Прежде всего, вы должны использовать *ngFor, чтобы перечислить все ваши варианты:

html:

<a class="item" *ngFor="let choice of checks; let i=index">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden" [value]="choice.value" (change)="onCheckChange($event)">
        <label>{{choice.title}}</label>
    </div>
</a>

компонент:

public checks: Array<choices> = [
  {title: '4 GB', value: '4'},
  {title: "8 GB", value: '8'},
  {title: "16 GB", value: '16'}
];

public onCheckChange(event) {
    // do some things here
}

Кроме того, вы должны использовать Reactive Forms для проверки вашего выбора: https://angular.io/guide/reactive-forms

person Nico Schuck    schedule 16.01.2020
comment
Да, я использую ReactiveForms и да, я использую *ngFor. Код в моем вопросе - это всего лишь образец... В любом случае, мне было недостаточно ясно, я отредактировал свой вопрос. Пожалуйста, прочтите еще раз. Благодарю вас! - person smartmouse; 16.01.2020
comment
Если вы просто хотите, чтобы ваш диапазон также активировал весь флажок, как насчет использования material.angular. io/components/checkbox/обзор? - person Nico Schuck; 16.01.2020
comment
Я не использую материал. - person smartmouse; 16.01.2020

Вы должны создать логический массив и привязать его к своим флажкам.

.ts-файл

  myArray: any[] = [
 {
      "size": "2GB",
      "value":false
    },
    {
      "size": "4GB",
      "value":false
    },
    {
      "size": "8GB",
      "value":false
    }
]

.html файл

<div *ngFor="let data of myArray">
 <a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden" [(ngModel)]="data.value" (ngModelChange)="changeHandler()">
        <label>{{data.size}}</label>
    </div>
 </a>
</div>

Рабочая демонстрация: ссылка

person Himanshu Singh    schedule 16.01.2020
comment
Я не ясно выразился, извините за это. Я говорю о захвате событий. Я отредактировал свой вопрос. В вашем фрагменте, если вы нажмете на метку или на весь элемент, я не выберу соответствующий флажок. - person smartmouse; 16.01.2020

Вы можете сделать что-то вроде этого:

const ramOptions = [
  {
    id: 1,
    size: '4 GB'
  },
  {
    id: 2,
    size: '8 GB'
  },
  {
    id: 3,
    size: '16 GB'
  }
]

И в html:

<a class="item" *ngFor="let option of ramOptions">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden" (change)="onSelect(option.id)">
        <label>{{option.size}}</label>
    </div>
</a>

Если в файле .js/.ts вы можете создать интерфейс для определения обработчика. Как только:

onSelect(id: string) {
  ...
}
person Felipe Malara    schedule 16.01.2020
comment
Я не ясно выразился, извините за это. Я говорю о захвате событий. Я отредактировал свой вопрос. - person smartmouse; 16.01.2020
comment
Вы можете поместить вызов функции в элемент ‹a› - person Felipe Malara; 16.01.2020