angular2 wysiwyg tinymce implementation and 2-way-binding

前提是你 提交于 2019-11-26 23:29:39

问题


Hi I'm trying to implement tinymce into an angular 2 component for a small forum to create a new thread. I want the content of the textarea (tinymce) be 2-way-binded to a variable inside the component. So far the submit button works but the keyup event doesn't.

export class ForumNewThreadComponent implements OnInit{

  constructor(){}
  ngOnInit():any {
    tinymce.init(
      {
        selector: ".tinyMCE",
      })
  }

text:string;
  submit(){
    this.text = tinymce.activeEditor.getContent();
  }
  getTinymceContent(){
    this.text = tinymce.activeEditor.getContent();
  }
}

and view

<div class="thread-body">
    {{getValue}}
    <textarea class="tinyMCE" style="height:300px" (keyup)="getTinymceContent()">

    </textarea>
    <button class="btn btn-primary" (click)="submit()">Submit</button>
  </div>

回答1:


I would implement a custom value accessor for this:

const TINY_MCE_VALUE_ACCESSOR = new Provider(
  NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => TinyMceValueAccessor), multi: true});

@Directive({
  selector: 'textarea[tinymce]',
  host: { '(keyup)': 'doOnChange($event.target)' },
  providers: [ TINY_MCE_VALUE_ACCESSOR ]
})
export class DateValueAccessor extends DefaultValueAccessor {
  @Input()
  tinymce:any;

  onChange = (_) => {};
  onTouched = () => {};

  writeValue(value:any):void {
    if (value!=null) {
      super.writeValue(value.toString());
    }
  }

  doOnChange(elt) {
    this.onChange(this.tinymce.activeEditor.getContent());
  }
}

I would use it this way:

<textarea [tinymce]="tinymce" style="height:300px" [(ngModel)]="text">

</textarea>

and in your component class:

@Component({
  (...)
  directives: [ DateValueAccessor ]
}) 
export class ForumNewThreadComponent implements OnInit{
  constructor(){}
  ngOnInit():any {
    tinymce.init({
      selector: "[tinymce]"
    })
  }

  text:string;
}



回答2:


Or do it like this, using tmce's change event and NgZone

constructor(public zone:NgZone) {}

ngOnInit():any {
    tinymce.init(
      {
        selector: ".tinyMCE",
        setup: (ed) => {
          ed.on('keyup change', (ed, l) => {
            this.zone.run(()=> {
              this.text = tinymce.activeEditor.getContent();
            });
          });

        }
      })
  }

This would fail once you have more than one instance on tmce in one component. Put this logic in a directive like Thierry's implementation.




回答3:


I wanted to say I did the same implementation as stated above, but I came across this weird error and banged my head around and around fixing this error of 'cannot modify NodeName of Null', so finally today I fixed the error and I wanted to share it, so people won't have to search it anymore what the error might be. I know this is an old post my apologies for that.

  1. get the code of github (directive). link below. thankyou @Abhijith Nagaraja for the post.

https://github.com/Abhijith-Nagaraja/tinymce-docs/blob/master/integrations/angular2.md#sample-directive-implementation-with-ngmodel-two-way-binding

2. add two variables to the directive

private editor;
private init: boolean = false;

rewrite the method

writeValue(value: any): void {
    // ...
} 

to

writeValue(value: any): void {
    // This check is necessary because, this method gets called before editor gets initialised.
    // Hence undefined/null pointer exceptions gets thrown
    if (this.init) {
      if (tinymce.get(this.selector)) {
         tinymce.get(this.selector).setContent(value, {format: 'raw'});
      }
   }
}

replace in ValueOnChange(change: boolean) this.val = tinymce.activeEditor.getContent();

to

if (tinymce.activeEditor) {         
    this.val = tinymce.activeEditor.getContent();
}

rewrite tinymce.init(options)

to

tinymce.init(options).then(() => {
    this.init = true;
});

and last add a ngOnDestroy method

ngOnDestroy() {
    tinymce.remove(this.editor);
}

This has fixed the error for me and also fixed for me when the editor was already initialized and I had reuse it, it wouldn't compile. but now because of the ngOnDestroy I now can destroy the editor and the afterViewInit will recall the tinymce.init




回答4:


I know this is a little old post. But after scratching my head for over 2 days. I was finally able to figure this out and thought this might be useful to others. So sharing it here

https://github.com/Abhijith-Nagaraja/tinymce-docs/blob/master/integrations/angular2.md#sample-directive-implementation-with-ngmodel-two-way-binding



来源:https://stackoverflow.com/questions/36841335/angular2-wysiwyg-tinymce-implementation-and-2-way-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!