【问题标题】:ckeditor angular ControlValueAccessorckeditor 角度 ControlValueAccessor
【发布时间】:2020-05-15 06:00:43
【问题描述】:

我正在尝试创建一个实现 ControlValueAccessor 的组件。自定义表单控件将实现一个 div,该 div 将成为一个 ckeditor 控件,然后将使用 Forms 验证器,但它不会在自定义元素上调用 ngAfterViewInit 并且不会创建 ckeditor 控件。我应该有 ng-container 标签吗?

自定义元素视图

<ng-container *ngIf="controlGroup.controls.value">
    <Editor [formControl]="controlGroup.controls.value">
    </Editor>
</ng-container>

组件

import { Component, forwardRef, NgZone, EventEmitter, Inject, Input, Output, } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormBuilder, FormGroup, Validators, FormControl  } from '@angular/forms';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@Component({
    selector: 'Editor',
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => Editor),
            multi: true
        }
    ],
    template: `<div [attr.id]="editorId" contenteditable="true"
                style="width: 100% !important; overflow: hidden"
                class="form-control sentence-part-values-inline sentence-part-values-inline-textbox-number">
                </div>`,
})



export class Editor implements ControlValueAccessor {
    @Input() public model: OrderTemplateTool.Core.Sentences.EmeticRisks.RegimenDescriptorSentencePartModel;
    getModel(): OrderTemplateTool.Core.Sentences.EmeticRisks.RegimenDescriptorSentencePartModel {
        return this.model;
    }
    editorId: string;   

    @Output() public modelchange: EventEmitter<any> = new EventEmitter();
    public onModelChange(): void {
       // this.validate();
        this.modelchange.next(this.getModel());
    }

    constructor(@Inject(NgZone) private ngZone: NgZone) { this.editorId = "regimen-descriptor-" + (<any>window).newGuid();    }

    onChange: any = () => { }
    onTouch: any = () => { }
    val = ""

    set value(val) {
        if (val !== undefined && this.val !== val) {
            this.val = val
            this.onChange(val)
            this.onTouch(val)
        }

    }

    writeValue(value: any) {
        this.value = value
    }

    registerOnChange(fn: any) {
        this.onChange = fn
    }

    registerOnTouched(fn: any) {
        this.onTouch = fn
    }

    ngAfterViewInit() {


        var self = this;

        this.ngZone.runOutsideAngular(() => {
            console.log('Procssing ngZone');
            (<any>window).CKEDITOR.config.autoParagraph = false;
            console.log('ngAfterViewInit');
            console.log(this.editorId);
            if (!(<any>window).CKEDITOR.instances[this.editorId]) {
                (<any>window).CKEDITOR.disableAutoInline = true;
                (<any>window).CKEDITOR.inline(self.editorId, {
                    enterMode: 2,
                    toolbar: [
                        {
                            name: 'basicstyles', groups: ['basicstyles', 'cleanup'],
                            items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript']
                        },
                        {
                            name: 'source',
                            items: ['Sourcedialog']
                        }
                    ],
                    removeButtons: '',  //override default value from config.js of CKEDITOR,
                    extraPlugins: 'sourcedialog'
                });

                let editor = (<any>window).CKEDITOR.instances[self.editorId];
                console.log(editor);                  (<any>window).CKEDITOR.instances[this.editorId].setData(this.model.Value);
                                    (<any>window).CKEDITOR.instances[this.editorId].on("change", () => {
                    self.model.Value = (<any>window).CKEDITOR.instances[self.editorId].getData();    
                    var editorName = this.editorId;                        (<any>window).CKEDITOR.instances[editorName].updateElement();    
                    self.onModelChange();    
                });

                (<any>window).CKEDITOR.instances[this.editorId].on("instanceReady", (ev) => {
                    var editor = ev.editor;
                    editor.setReadOnly(false);
                });
            }
        });
    }

    ngOnDestroy() {
        this.ngZone.runOutsideAngular(() => {
            var editor = (<any>window).CKEDITOR.instances[this.editorId];
            if (editor) {
                editor.destroy(true);
            }
        });
    }
}

【问题讨论】:

    标签: angular ckeditor


    【解决方案1】:

    试试这样, html文件->

    <ckeditor
            [config]="editorConfig" [editor]="Editor"
            required formControlName="content"
            data="" name="text"
          >
          </ckeditor>
    

    ts 文件 ->

    public editorConfig = {
        placeholder: 'Question Content'
      };
    
    let form = this.fb.group({
          content: ['', [
            Validators.required
          ]]
        });
    

    【讨论】:

      【解决方案2】:

      如果没有父(或祖先)formGroup 指令,则不能使用 formControlName/formGroupName/formArrayName 名称。

      这意味着你需要有这样的东西:

      <form [formGroup]="yourFormGroup">
       <!-- ... -->
       <custom-element formControlName="name"></custom-element>
       <!-- ... -->
      </form>
      

      但是,如果您不想担心将其包含在其他任何地方,您可以使用 formControl 指令:

      <custom-element [formControl]="yourFormControlInstance"></custom-element>
      

      【讨论】:

      • 当我使用 formControl 时出现此错误 core.umd.js:2838 例外:找不到具有未指定名称属性的控件
      • 您是否也添加了名称属性?那么是否仍然显示错误?
      • 你的意思是
      • 没关系,您不需要 name 属性。 controlGroup.controls.Value 控件是在那个时候定义的吗?
      • 应该有什么方法可以确定吗?
      猜你喜欢
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 2016-10-03
      相关资源
      最近更新 更多