Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Angular JS中使用CKEditor内容更新textarea值_Javascript_Angularjs_Ckeditor_Angularjs Directive_Wysiwyg - Fatal编程技术网

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

Javascript 在Angular JS中使用CKEditor内容更新textarea值,javascript,angularjs,ckeditor,angularjs-directive,wysiwyg,Javascript,Angularjs,Ckeditor,Angularjs Directive,Wysiwyg,我正在使用最新的CKEditor(标准版本),并基于此 ,我执行了这样一个角度指令 var cmsPlus = angular.module('cmsPlus', []); cmsPlus.directive('ckEditor', function() { return { require: '?ngModel', link: function(scope, elm, attr, ngModel) { var ck = CKEDITOR.replace(elm

我正在使用最新的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);
      };
    }
  };
});
当我在ckeditorgui模式下键入内容时,它工作得很好,在这里,我将键入的内容获取到textarea的ng模型

但当我切换到代码编辑器时,即使切换回GUI,它也无法获得更新的内容。需要在图形模式下再次键入某个内容

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

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


我希望这个问题与我的类似。 CK编辑器有自己的元素,它将这些元素注入到DOM中,并且已经呈现了Angular,因此您需要为它转换到代码编辑器时设置侦听器。如果您没有监听更改,那么Angular无法正确绑定,因为它不知道DOM中的更改。我在tinymce和弹出的模态中遇到了类似的情况


您的指令运行良好

有一个名为sourcearea的插件,在源代码模式下控制CKEditor的行为。在处理输入的插件代码中,我没有看到任何事件被触发。当CKEditor返回到时,我们可以使用两个事件来捕获 GUI模式。事件为数据就绪

我已经更新了您的示例以使用dataReady事件,因此它在切换回时会更新文本区域。我还将粘贴状态事件更改为更改,因为它是在版本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);
      };
    }
  };
});
不管怎样,也许你可以从中找出如何解决最后一个关键问题。快到了


编辑:更新了正确版本的fiddle链接

我知道这个问题已经得到了回答,但我想我应该加入到将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
对于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);
        };
      }
    };
  }
);
然后在HTML中:

<textarea ckeditor data-ng-model="myModel"></textarea>

现在,我来解释一下

为了完整性,我添加了粘贴和选择更改处理程序,但结果表明选择更改处理程序是必要的。我发现,如果我选择了all并点击delete,那么在编辑器提交表单时,没有将焦点转移,提交时模型中没有反映出的更改。选择更改处理程序解决了这个问题


将CKEditor与angularjs集成对我的项目至关重要,因此如果我发现更多的“Gotchas”,我将更新此答案。

对于我来说,@Mjonir74的答案是有效的,但只要我在一个页面上有多个编辑器实例,并且还必须考虑编辑模式而不仅仅是创建模式,当您回到包含编辑器的页面时,事情开始无法正常工作。基本上是在编辑模式下,第一次访问页面时,一切都很好,文本应该在编辑器中。但对同一页面的任何连续访问都会使编辑器空着,没有文本

以下是我的工作方式:

    app.directive('appWysiwygBlock', function() {
    return {
        require: 'ngModel',
        restrict: 'E',
        templateUrl: 'modules/app/templates/directives/wysiwyg-block.html',
        scope: {
            error: '=',
            config: '='
        },
        link: function(scope, element, attrs, ngModel) {

            if (typeof CKEDITOR == 'undefined' || !ngModel) {
                return;
            }

            scope.required = attrs.required || false;
            scope.cols = attrs.cols || 6;

            scope.label = attrs.label || attrs.name;
            scope.name = attrs.name || scope.label;
            if (scope.name) {
                scope.name = scope.name.toLowerCase().replace(/[^a-z0-9]/gi, '_');
            }

            var defaultConfig, config, editor, updateModel;

            config = scope.config || {};
            defaultConfig = {
                customConfig: '/modules/app/ckeditor-config.js'
            };

            config = element.extend({}, defaultConfig, config);
            editor = CKEDITOR.replace(element.find('textarea:first')[0], config);

            updateModel = function() {
                return scope.$apply(function() {
                    return ngModel.$setViewValue(editor.getData());
                });
            };

            editor.on('instanceReady', function() {
                editor.on('change', updateModel);
                editor.on('dataReady', updateModel);
                editor.on('key', updateModel);
                editor.on('paste', updateModel);
                editor.on('selectionChange', updateModel);
                return editor.setData(ngModel.$viewValue);
            });

            return ngModel.$render = function() {
                return editor.setData(ngModel.$viewValue);
            };
        }
    };
});
我把它当作

<app-wysiwyg-block label="Description" name="description" ng-model="item.description" error="fieldErrors.description" required="true" cols="12"></app-wysiwyg-block>


在一个页面中执行任意次数,它在所有模式下都能正常工作。

我认为这不是问题所在,因为OP使用的是本机ckeditor事件和API,而不是DOM绑定。如果在单击源代码时检查文本区域中的元素,则该指令将消失。devo不是DOM绑定,但是当单击源代码按钮时,ckedit正在删除他的指令,因此AngularJS不知道绑定到什么,因为该指令已被销毁。DOM更新时没有Angular的knolwedge。尝试将指令设置为类并允许转换。限制:“C”,替换:真,转移:真,编辑:grr。。。显然,ckEdit也会破坏您的类:/I我希望我的思路是正确的,但尝试了其他方法。难道没有人建议直接绑定到cke进入源代码模式时创建的DOM元素吗?那不管用吗?我认为这很聪明。你是如何使用指令的?如果您可以提供一个使用JSFIDLE或plnkr的真实示例,那么会更容易提供帮助@JonasHartmann检查我的链接,当我进入GUI时,我们可以看到即时更新,而在使用源代码视图键入时,它不会更新。@Jonas-你能告诉我为什么选择在ck.setdata中使用$viewValue而不是$modelValue吗。我开始看到一些ckEditor指令使用其中一个,而其他指令使用另一个。@Alan-首先,我刚刚修改了OP中的代码。但我认为使用$viewValue更有意义,因为当我们调用ck.setdata时,我们希望将数据呈现给用户。$viewValue是准备显示的数据。我建议在两侧添加字符串修剪,这样您就可以可靠地测试表单修改。请参见jsfiddle.net/fdD63/12。CKEditor总是添加一个换行符,因此来自数据库的传入HTML可能不匹配,即使唯一的区别是CKEditor添加的换行符。如何上载多个图像,如@rajeshpanwar中的图像:请将您的评论转换为问题。选择更改处理程序保存了我!谢谢,我也是!。。非常感谢:)如果使用nanospell,请在textarea replace工作后添加它。如下所示:nanospell.ckeditor(元素[0].id,{dictionary:“en”,server:“asp.net”});