使用Angular JS中的CKEditor内容更新textarea值

dev*_*evo 14 javascript wysiwyg ckeditor angularjs angularjs-directive

我正在使用最新的CKEditor(标准版)并基于这个 问题,我已经实现了这样的角度指令,

var cmsPlus = angular.module('cmsPlus', []);

cmsPlus.directive('ckEditor', function() {
  return {
    require: '?ngModel',
    link: function(scope, elm, attr, ngModel) {
      var ck = CKEDITOR.replace(elm[0]);

      if (!ngModel) return;

      ck.on('pasteState', function() {
        scope.$apply(function() {
          ngModel.$setViewValue(ck.getData());
        });
      });

      ngModel.$render = function(value) {
        ck.setData(ngModel.$viewValue);
      };
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

当我在CKEditor GUI模式下输入内容时,它工作正常,这里我将输入的内容添加到textarea的ng-model中.

但是当我切换到代码编辑器时,即使在切换回GUI之后也没有获得更新的内容.需要在图形模式下再次键入内容.

我的指令有什么问题?或者我可以使用其他一些CKEditor事件扩展此指令吗?

我想为表单提交或其他内容添加更多事件.

在这里演示.

Jon*_*nas 27

你的指令运作良好.

有一个名为sourcearea的插件在源模式下控制CKEditor行为.我无法在该插件的代码中看到任何事件被触发以处理输入.当CKEditor返回GUI模式时,我们可以使用两个事件来捕获 .事件是ariaWidget和dataReady.

我已经更新了您的示例以使用dataReady事件,因此它在切换回时会更新textarea.我也改变了pasteState事件来改变,如丹卡拉贾说,它是在4.2版本中引入的. 更新的小提琴可以在这里找到

我找到的一个几乎就是解决方案是收听关键事件并更新模型.它几乎就在那里,因为看起来事件只是针对按下的旧键被触发.所以最后一把钥匙总是丢失.

var cmsPlus = angular.module('cmsPlus', []);

cmsPlus.directive('ckEditor', function() {
  return {
    require: '?ngModel',
    link: function(scope, elm, attr, ngModel) {
      var ck = CKEDITOR.replace(elm[0]);

      if (!ngModel) return;

      ck.on('instanceReady', function() {
        ck.setData(ngModel.$viewValue);
      });

      function updateModel() {
          scope.$apply(function() {
              ngModel.$setViewValue(ck.getData());
          });
      }

      ck.on('change', updateModel);
      ck.on('key', updateModel);
      ck.on('dataReady', updateModel);

      ngModel.$render = function(value) {
        ck.setData(ngModel.$viewValue);
      };
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

无论如何,也许你可以从中找出如何解决最后一个关键问题.它几乎就在那里!

编辑:更新小提琴链接到正确的版本


Mjo*_*r74 9

我知道这个问题已经得到了回答,但是我想我已经完成了将CKEditor 4.4.4与angularjs 1.2集成的工作.这是我在coffeescript中的代码:

'use strict'

angular.module 'core', []

.directive 'ckeditor', ->
    require: '?ngModel'
    link: (scope, element, attrs, ngModel) ->
        config =
            # CKEditor config goes here

        editor = CKEDITOR.replace element[0], config

        return unless ngModel

        editor.on 'instanceReady', ->
            editor.setData ngModel.$viewValue

        updateModel = ->
            scope.$apply ->
                ngModel.$setViewValue editor.getData()

        editor.on 'change', updateModel
        editor.on 'dataReady', updateModel
        editor.on 'key', updateModel
        editor.on 'paste', updateModel
        editor.on 'selectionChange', updateModel

        ngModel.$render = ->
            editor.setData ngModel.$viewValue
Run Code Online (Sandbox Code Playgroud)

对于coffeescript文盲,这里是编译的javascript:

'use strict';
angular.module('core', []).directive('ckeditor', function() {
    return {
      require: '?ngModel',
      link: function(scope, element, attrs, ngModel) {
        var config, editor, updateModel;
        config = {
            // CKEditor config goes here
        }
        editor = CKEDITOR.replace(element[0], config);
        if (!ngModel) {
          return;
        }
        editor.on('instanceReady', function() {
          return editor.setData(ngModel.$viewValue);
        });
        updateModel = function() {
          return scope.$apply(function() {
            return ngModel.$setViewValue(editor.getData());
          });
        }};
        editor.on('change', updateModel);
        editor.on('dataReady', updateModel);
        editor.on('key', updateModel);
        editor.on('paste', updateModel);
        editor.on('selectionChange', updateModel);
        return ngModel.$render = function() {
          return editor.setData(ngModel.$viewValue);
        };
      }
    };
  }
);
Run Code Online (Sandbox Code Playgroud)

然后在HTML中:

<textarea ckeditor data-ng-model="myModel"></textarea>
Run Code Online (Sandbox Code Playgroud)

现在,作一个解释.

为了完整性,我添加了粘贴和选择更改处理程序,但事实证明选择更改处理程序是必要的.我发现,如果我选择了all并点击删除,那么 - 无需关注编辑器提交的表单,这些更改不会反映在提交的模型中.选择更改处理程序解决了该问题.

将CKEditor与angularjs集成对我的项目至关重要,所以如果我再找到"Gotchas",我会更新这个答案.