Невозможно исправить значение компонента PrimeNG p-editor

Я создал форму, которая использует элемент p-editor для написания форматированного текста, но столкнулся с проблемой: редактор создает и отправляет форматированный текст, но когда мы хотим обновить форму, используя значение с сервера, используя метод angular реактивной формы patchValue не обновляет редактор по мере необходимости. Вот мой код

Шаблон:

<form>
  <div class = "col-12 my-3">
      <label class = "small font-bold" for = "content" i18n>Requirments</label>
      <p-editor formControlName = "content" id = "content" placeholder = "content..." [style] = "{ height: '200px' }"></p-editor>
    </div>
</form>

компонент:

export class SampleComponent implements OnChanges {

 @Input() data?: {content: string};
 formEditor: FormGroup

 constructor(
    private _fb: FormBuilder,
  ) 
 {
  this.formEditor = this._fb.group({
     content: ["", Validators.required]
  })
 }

 ngOnChanges() {
// I verified and indeed the data comes when there is a change 
    if (this.data) {
      this.patchEditorForm(this.data);
    }
 }

 private patchEditorForm = (data: {content: string}) => {
    this.formEditor.patchValue({
      content: post.content
    })
 }

}

Я использую декоратор AfterViewInit и Angular @ViewChild, но он все равно не работает.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
220
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

data — это объект, объекты хранятся как ссылки на память в javascript, следует отметить, что даже когда вы меняете content, которое является внутренним свойством data, ссылка на data в памяти остается той же, поэтому даже когда было изменение данных во внутренних свойствах, Angular не имеет возможности определить, что что-то изменилось.

Решение состоит в том, чтобы изменить ссылку на память. Распространенный способ сделать это называется деструктуризацией объекта. Когда мы создаем новый массив и обновляем исходные свойства в новые, команда будет this.data = { ...this.data };

После этого изменение будет обнаружено. Рабочий пример ниже!

ПОЛНЫЙ КОД:

ОСНОВНОЙ

import { Component } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'editor-basic-demo',
  standalone: true,
  imports: [ChildComponent],
  template: `
    <app-child [data] = "data"/>
  `,
})
export class EditorBasicDemo {
  name = 'Angular';
  data = {
    content: '',
  };

  ngOnInit() {
    setInterval(() => {
      this.data.content = `${Math.random()}`;
      this.data = { ...this.data }; // use object destructuring to create a new reference of memory for the array
      // this will cause angular to detect a change and trigger ngOnChanges when changed!
    }, 2000);
  }
}

РЕБЕНОК

import { Component, Input } from '@angular/core';
import { EditorModule } from 'primeng/editor';
import {
  FormBuilder,
  FormGroup,
  Validators,
  ReactiveFormsModule,
} from '@angular/forms';

@Component({
  selector: 'app-child',
  standalone: true,
  imports: [ReactiveFormsModule, EditorModule],
  template: `
  asd
    <form [formGroup] = "formEditor">
      <div class = "col-12 my-3">
          <label class = "small font-bold" for = "content">Requirments</label>
          <p-editor formControlName = "content" id = "content" placeholder = "content..."></p-editor>
        </div>
    </form>
  `,
})
export class ChildComponent {
  @Input() data?: { content: string };
  formEditor: FormGroup = new FormGroup({});

  constructor(private _fb: FormBuilder) {
    this.formEditor = this._fb.group({
      content: ['', Validators.required],
    });
  }

  ngOnChanges() {
    // I verified and indeed the data comes when there is a change
    if (this.data) {
      this.patchEditorForm(this.data);
    }
  }

  private patchEditorForm = (data: { content: string }) => {
    this.formEditor.patchValue({
      content: data.content,
    });
  };
}

Демо-версия Stackblitz

Я работал над этой идеей, и обнаружение изменений работает так же, как и обнаружение данных. Я думаю, проблема заключается в исправлении значения p-редактора PrimeNG. По той или иной причине это просто не сработало, и я искал в Интернете способ сделать это, но не смог его найти. Есть ли другие способы исправить это значение или какой-либо другой подход к нему?

Mofiro Jean 17.05.2024 23:33

@MofiroJean проверьте свою версию prime ng, затем перейдите на GitHub в ветках, выберите свою версию и откройте package.json, там проверьте версию quill, убедитесь, что в вашем проекте установлена ​​та же версия, вы также можете проверить папку node_modules внутри вашего проекта для package.json

Naren Murali 18.05.2024 06:39

Хорошо, отлично, дай мне попробовать, я никогда об этом не думал.

Mofiro Jean 18.05.2024 10:44
Ответ принят как подходящий

Наконец я нашел способ обойти это, используя декоратор @ViewChild в Angular. Вот как я изменил код для достижения указанных целей:

import { Component, Input } from '@angular/core';
import { EditorModule, Editor } from 'primeng/editor';
import {
  FormBuilder,
  FormGroup,
  Validators,
  ReactiveFormsModule,
} from '@angular/forms';

@Component({
  selector: 'app-child',
  standalone: true,
  imports: [ReactiveFormsModule, EditorModule],
  template: `
    <form [formGroup] = "formEditor">
      <div class = "col-12 my-3">
          <label class = "small font-bold" for = "content">Content:</label>
          <p-editor #editor formControlName = "content" id = "content" placeholder = "content..."></p-editor>
        </div>
    </form>
  `,
})
export class ChildComponent {
  @Input() data?: { content: string };
  formEditor: FormGroup = new FormGroup({});
  // using @ViewChild decorator
  @ViewChild('editor') public editor!: Editor

  constructor(private _fb: FormBuilder) {
    this.formEditor = this._fb.group({
      content: ['', Validators.required],
    });
  }

  ngOnChanges() {
    // I verified and indeed, the data comes when there is a change
    if (this.data) {
      // make use of the writeValue() of the editor object
      this.editor.writeValue(this.data.content);
    }
  }
}

Кроме того, обязательно запустите команду npm install --save @types/quill, потому что при проверке этого метода я столкнулся с ошибкой, связанной с импортом Delta из библиотеки.

Другие вопросы по теме