двусторонняя привязка флажка ngFor Angular2

Я создаю проект Angular2 и имею проблему с двусторонней привязкой для флажка.

У меня есть класс с именем listItem и List следующим образом:

export class ListItem {
  public count: number;
  public value: string;
  public checked: boolean;

  constructor(count: number, value: string, checked: boolean) {
    this.count = count;
    this.value = value;
    this.checked = checked;
  }
}

export class MyList{
  public category: string;
  public listItem : ListItem [];

  constructor(category: string, listItem : ListItem []) {
    this.category = category;
    this.listItem = listItem ;
  }
}

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

<div *ngFor="let list of myList; let listIndex = index;">
  <div *ngFor="let item of list.listItems; let itemIndex = index;">
    <input type="checkbox" [name]="list.category + item.value"
         (change)="item.checked = !item.checked"
         [ngModel]="item.checked" />
  </div
</div>

но значение всегда ложно и onClick. Я пытался использовать [(ngModel)], но тоже не работал. Я также попытался сделать функцию:

(change)="oncheck(listIndex, itemIndex)"

oncheck(listIndex: number, itemIndex: number) {
   this.myList[listIndex].listItems[itemIndex].checked =  
           !this.myList[listIndex].listItems[itemIndex].checked;
  } 

но я получил эту ошибку:

Невозможно присвоить доступному только для чтения свойству «checked» объекта «[object Object]»

почему так и как это исправить? благодарю вас


person Samy Sammour    schedule 06.06.2017    source источник
comment
Возможен дубликат. Можете ли вы уточнить, как [(ngModel)] ведет себя в вашем случае? Он должен работать нормально. stackoverflow.com/questions/40214655 /   -  person trungk18    schedule 06.06.2017
comment
Я добавляю это так: [(ngModel)]=item.checked, и я всегда получаю false. без какой-либо ошибки.   -  person Samy Sammour    schedule 06.06.2017
comment
В смысле, даже когда вы установили флажок, и он все еще ложный?   -  person trungk18    schedule 06.06.2017
comment
Я пробовал этот пример, но тоже не работал. и почему я получаю сообщение об ошибке, когда пытаюсь создать событие?   -  person Samy Sammour    schedule 06.06.2017
comment
да, значение «checked» в последнем по умолчанию равно false. так что неважно, сколько я проверяю. список по-прежнему ложный, когда я проверяю отладчик и после нажатия кнопки все флажки возвращаются к ложным, что является значением по умолчанию. Я думаю, что односторонняя привязка работает хорошо, но набор значений не работает. возможно, причиной может быть сообщение об ошибке. но я этого не понимал и не знаю почему.   -  person Samy Sammour    schedule 06.06.2017
comment
Хороший вопрос, но у меня нет вашего рабочего кода, поэтому я не могу не ответить на него. Только что создал простой плункер для вас, обычно он работает так. plnkr.co/edit/oiDwez?p=preview   -  person trungk18    schedule 06.06.2017
comment
это plnkr: plnkr.co/edit/PLdXtiAFGHfF7nvnvKXN он не будет работать правильно, потому что я удалил URL и заголовки в целях безопасности. но я думаю, что в нем есть все, что вам нужно, чтобы заставить его работать   -  person Samy Sammour    schedule 06.06.2017
comment
Давайте продолжим обсуждение в чате.   -  person trungk18    schedule 06.06.2017


Ответы (1)


Вы можете использовать директиву md-checkbox material2 для создания стилизованных элементов. На мой взгляд, это не совсем двусторонняя привязка, это просто комбинация односторонней привязки в обоих направлениях (шаблон - источник данных и источник данных - шаблон).

ОБНОВЛЕНИЕ: я создал небольшой plnkr, чтобы воспроизвести вашу ситуацию: http://plnkr.co/edit/cr7TokiqSaBGli7mgCBM

@Component({
  selector: 'my-app',
  template: `
    <div *ngFor="let element of elements; let i = index;">
    <span>Val: {{element}}</span>
      <input type="checkbox"
       [checked]="element" (change)="handleChange(element, i)">
    </div>
  `,
})
export class App {
  elements= [
    false,
    true,
    false,
  ]:

  handleChange(val: boolean, index: number){
    console.log("Index: "+index);
    console.log("Val:  "+val);
    this.elements[index] = !val;
  }

Элементы в списке отображаются правильно, но события изменения в некоторых случаях изменяют значения неправильных позиций в массиве элементов. Я посмотрю позже

ОБНОВЛЕНИЕ: рефакторинг plnkr

Пожалуйста, проверьте: http://plnkr.co/edit/Ich0g5kzSiQINZjh3VYo.

Я внес некоторые изменения в plnkr, который вы мне прислали.

Я изменил переменные итерации с const на let (учитывая, что их значения не являются постоянными во время выполнения циклов).

Как я упоминал ранее, скорее всего, есть 2 возможности: классы в .ts транспилируются неправильным образом в .js (члены класса по умолчанию устанавливаются как доступные только для чтения) или что-то не так в том, как вы вручную сопоставляя значения с экземплярами класса.

person Jota.Toledo    schedule 06.06.2017
comment
Мне не разрешено добавлять дополнительную библиотеку - person Samy Sammour; 06.06.2017
comment
спасибо за решение, я пробовал, но это не сработало. та же проблема. пожалуйста, посмотрите на сообщение об ошибке, упомянутое в вопросе. - person Samy Sammour; 06.06.2017
comment
Я не вижу сообщения об ошибке, которое запускается на plnkr. У вас есть небольшой тестовый набор, который я мог бы использовать? Ошибка странная, учитывая, что свойство checkd не определено как доступное только для чтения или подобное - person Jota.Toledo; 06.06.2017
comment
Я думаю проблема в наборе. потому что, когда я пытаюсь реализовать событие, как указано в вопросе, я получаю сообщение об ошибке: невозможно назначить свойство только для чтения «проверено» объекта «[объект объекта]», но почему? - person Samy Sammour; 06.06.2017
comment
По какой-то причине объекты в вашем массиве защищены от записи. Откуда вы создаете/получаете эту коллекцию? - person Jota.Toledo; 06.06.2017
comment
из лазурного поиска подпишитесь как json, а затем вручную. см. plnkr plnkr.co/edit/PLdXtiAFGHfF7nvnvKXN - person Samy Sammour; 06.06.2017
comment
в исходном коде определено много констант, скорее всего, одна из них вызывает проблему. Я взгляну - person Jota.Toledo; 06.06.2017
comment
вы можете попробовать вручную установить через поле ввода или подобное другое свойство в любом из элементов? например, попробуйте установить элемент «значение» и сообщите мне, если вы получите ту же ошибку - person Jota.Toledo; 06.06.2017
comment
Я пытался, и я получаю ту же ошибку для всех свойств и для категории - person Samy Sammour; 06.06.2017
comment
вы создали проект с помощью angular cli или вручную? Я думаю, что это как-то связано с тем, как файлы .ts переводятся в файлы .js. - person Jota.Toledo; 06.06.2017
comment
используя угловой кли - person Samy Sammour; 06.06.2017
comment
о, спасибо, сегодня решил проблему. Это было так, как я называю метод. Я использовал избыточность, и, поскольку состояние избыточности неизменно, я не мог его изменить, и оно всегда было только для чтения. но когда я позвонил в сервис нормально, проблема решилась. но ваше решение было правильным. благодарю вас - person Samy Sammour; 07.06.2017