angular2 wysiwyg tinymce实现和双向绑定

时间:2016-04-25 12:59:42

标签: typescript angular tinymce wysiwyg rich-text-editor

您好我试图将tinymce实现为一个角度2组件,以便为一个小论坛创建一个新线程。 我希望textarea(tinymce)的内容被双向绑定到组件内的变量。到目前为止,提交按钮有效,但是keyup事件没有。

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();
  }
}

并查看

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

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

4 个答案:

答案 0 :(得分:5)

我会为此实现一个自定义值访问器:

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());
  }
}

我会这样用它:

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

</textarea>

并在您的组件类中:

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

  text:string;
}

答案 1 :(得分:2)

或者这样做,使用tmce的改变事件和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();
            });
          });

        }
      })
  }

如果在一个组件中有多个tmce实例,则会失败。 把这个逻辑放在像Thierry的实现这样的指令中。

答案 2 :(得分:2)

我想说我做了如上所述的相同实现,但是我遇到了这个奇怪的错误并且围绕着修复'cannot modify NodeName of Null'的这个错误而烦恼,所以最后今天我修复了错误,我想要分享它,所以人们将不再需要再搜索错误可能是什么。我知道这是一篇旧帖子,我为此道歉。

  1. 获取github(指令)的代码。下方链接。 感谢@Abhijith Nagaraja的职位。
  2. https://github.com/Abhijith-Nagaraja/tinymce-docs/blob/master/integrations/angular2.md#sample-directive-implementation-with-ngmodel-two-way-binding

    2。 将两个变量添加到指令

    private editor;
    private init: boolean = false;
    

    重写方法

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

    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'});
          }
       }
    }
    

    替换ValueOnChange(change: boolean) this.val = tinymce.activeEditor.getContent();

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

    重写tinymce.init(options)

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

    并最后添加ngOnDestroy方法

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

    这已经修复了我的错误,并且当编辑器已经初始化并且我已经重用它时它也修复了,它不会编译。但是现在由于ngOnDestroy我现在可以销毁编辑器而afterViewInit会召回tinymce.init

答案 3 :(得分:0)

我知道这是一个很老的帖子。但是在刮了我的头超过2天之后。我终于弄清楚了,并认为这可能对其他人有用。所以在这里分享

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