Angular — проблема двусторонней привязки в цикле ngFor

#angular #typescript

#angular #typescript

Вопрос:

Я пишу проект в Angular 10, и я не знаю почему, но свойство, отображаемое через ввод, отличается от того же свойства, отображаемого с использованием интерполяции в цикле ngFor. Эти значения начинают отличаться каждый раз, когда я добавляю новую пользовательскую секцию в массив customSections.

html-часть:

   <div
    class="uk-margin-top"
    *ngFor="
      let customSection of resume.customSections;
      let customSectionIndex = index
    "
  >
      <input
        class="uk-input uk-form-blank uk-text-bold uk-text-lead uk-padding-remove-left"
        type="text"
        name="sectionName"
        [(ngModel)]="customSection.sectionName
        "
        (ngModelChange)="getHtmlContent()"
      />

      <span>{{ customSection.sectionName }}</span>
  

часть typescript:

   onCustomSectionAddClick() {
    this.resume.customSections.push(new CustomSection("Untitled"));
    this.getHtmlContent();
  }
  

Все в порядке, но когда я нажимаю кнопку, чтобы добавить новый пользовательский раздел, то, как вы можете видеть, «Без названия» — это значение, отображаемое во входных данных для новых и более старых (ранее добавленных) пользовательских разделов, но span показывает другое значение (на этом скриншоте — значение ‘b’). Кто-нибудь знает, почему это может произойти?

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

Я сделал некоторое обходное решение, чтобы заставить его работать правильно, но все же я знаю, что это просто взлом (не очень хорошее решение):

сторона html:

       <input
        class="uk-input uk-form-blank uk-text-bold uk-text-lead uk-padding-remove-left"
        type="text"
        name="sectionName"
        (change)="onCustomSectionNameChange($event, customSectionIndex)"
        value="{{ customSection.sectionName }}"
      />

      <span>{{ customSection.sectionName }}</span>
  

сторона typescript:

   onCustomSectionNameChange(event: any, index: number) {
    this.resume.customSections[index].sectionName = event.target.value;
    this.getHtmlContent();
  }
  

Комментарии:

1. Вы не очищаете customerSection после нажатия кнопки. Это не происходит автоматически. Кроме того, что getHtmlContent() делает и почему вы выполняете это после каждого изменения?

2. @n9iels Я редактирую свой пост, чтобы показать, как я могу заставить его работать правильно (взломать). Метод getHtmlContent() просто отправляет данные в API и все

3. Я попытался воспроизвести ваш пример в StackBlitz и не смог воспроизвести ошибку. Может быть, что-то виновато в том, что вы не предоставили? Вот ссылка на StackBlitz: stackblitz.com/edit/angular-ivy-kokush?file=src/app /…

Ответ №1:

После нескольких часов размышлений об этой проблеме я заметил, какую простую ошибку я допустил. Атрибут name ввода должен быть уникальным в цикле ngFor. Итак, я изменил это:

   <input
    class="uk-input uk-form-blank uk-text-bold uk-text-lead uk-padding-remove-left"
    type="text"
    name="sectionName"
    [(ngModel)]="customSection.sectionName
    "
    (ngModelChange)="getHtmlContent()"
  />
  

к этому:

   <input
    class="uk-input uk-form-blank uk-text-bold uk-text-lead uk-padding-remove-left"
    type="text"
    name="sectionName-{{ customSectionIndex }}"
    [(ngModel)]="customSection.sectionName
    "
    (ngModelChange)="getHtmlContent()"
  />
  

И теперь все работает отлично. Спасибо вам, ребята, за попытку помочь мне и найти ошибку.