Я создал форму, которая использует элемент 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, но он все равно не работает.





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,
});
};
}
@MofiroJean проверьте свою версию prime ng, затем перейдите на GitHub в ветках, выберите свою версию и откройте package.json, там проверьте версию quill, убедитесь, что в вашем проекте установлена та же версия, вы также можете проверить папку node_modules внутри вашего проекта для package.json
Хорошо, отлично, дай мне попробовать, я никогда об этом не думал.
Наконец я нашел способ обойти это, используя декоратор @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 из библиотеки.
Я работал над этой идеей, и обнаружение изменений работает так же, как и обнаружение данных. Я думаю, проблема заключается в исправлении значения p-редактора PrimeNG. По той или иной причине это просто не сработало, и я искал в Интернете способ сделать это, но не смог его найти. Есть ли другие способы исправить это значение или какой-либо другой подход к нему?