Значение Bind Ckeditor для моделирования текста в углах и рельсах
Я хочу связать текст ckeditor с текстом ng-model
Мой взгляд
<fieldset>
<legend>Post to: </legend>
<div class="control-group">
<label class="control-label">Text input</label>
<div class="controls">
<div class="textarea-wrapper">
<textarea id="ck_editor" name="text" ng-model="text" class="fullwidth"></textarea>
</div>
<p class="help-block">Supporting help text</p>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Post</button>
<button class="btn">Cancel</button>
<button class="btn" onclick="alert(ckglobal.getDate())">Cancel123</button>
</div>
контроллер
function PostFormCtrl($scope, $element, $attrs, $transclude, $http, $rootScope) {
$scope.form = $element.find("form");
$scope.text = "";
$scope.submit = function() {
$http.post($scope.url, $scope.form.toJSON()).
success(function(data, status, headers, config) {
$rootScope.$broadcast("newpost");
$scope.form[0].reset();
});
};
$scope.alert1 = function(msg) {
var sval = $element.find("ckglobal");
//$('.jquery_ckeditor').ckeditor(ckeditor);
alert(sval);
};
}
PostFormCtrl.$inject = ["$scope", "$element", "$attrs", "$transclude", "$http", "$rootScope"];
Я хочу установить значение ckeditor в $scope.text во время формы submit
Thk заранее
Ответы
Ответ 1
CKEditor не обновляет текстовое поле при наборе текста, поэтому вам нужно позаботиться об этом.
Здесь директива, которая заставит привязку ng-модели работать с CK:
angular.module('ck', []).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);
};
}
};
});
В html просто используйте:
<textarea ck-editor ng-model="value"></textarea>
Предыдущий код обновит ng-модель при каждом изменении.
Если вы хотите обновить привязку при сохранении, переопределите плагин "save", чтобы ничего не делать, кроме события "сохранить" пожара.
// modified ckeditor/plugins/save/plugin.js
CKEDITOR.plugins.registered['save'] = {
init: function(editor) {
var command = editor.addCommand('save', {
modes: {wysiwyg: 1, source: 1},
readOnly: 1,
exec: function(editor) {
editor.fire('save');
}
});
editor.ui.addButton('Save', {
label : editor.lang.save,
command : 'save'
});
}
};
И затем, используйте это событие внутри директивы:
angular.module('ck', []).directive('ckEditor', function() {
return {
require: '?ngModel',
link: function(scope, elm, attr, ngModel) {
var ck = CKEDITOR.replace(elm[0]);
if (!ngModel) return;
ck.on('save', function() {
scope.$apply(function() {
ngModel.$setViewValue(ck.getData());
});
});
}
};
});
Ответ 2
Ответ Vojta частично работает
в этом посте я нашел решение
fooobar.com/questions/169738/...
окончательный код:
.directive('ckEditor', function() {
return {
require : '?ngModel',
link : function($scope, elm, attr, ngModel) {
var ck = CKEDITOR.replace(elm[0]);
ck.on('instanceReady', function() {
ck.setData(ngModel.$viewValue);
});
ck.on('pasteState', function() {
$scope.$apply(function() {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function(value) {
ck.setData(ngModel.$modelValue);
};
}
};
})
edit: удаленные неиспользуемые скобки
Ответ 3
Если вы просто хотите получить текст в редакторе textarea в angular, вызовите CKEDITOR.instances.editor1.getData();
, чтобы получить значение непосредственно в функции angularjs. См. Ниже.
В вашем html
В test.controller.js
(function () {
'use strict';
angular
.module('app')
.controller('test', test);
test.$inject = [];
function test() {
//this is to replace $scope
var vm = this;
//function definition
function postJob()
{
vm.Description = CKEDITOR.instances.editor1.getData();
alert(vm.Description);
}
}
})();
Ответ 4
Благодаря Vojta за отличную директиву. Иногда он не загружается. Вот исправленная версия, чтобы исправить эту проблему.
angular.module('ck', []).directive('ckEditor', function() {
var calledEarly, loaded;
loaded = false;
calledEarly = false;
return {
require: '?ngModel',
compile: function(element, attributes, transclude) {
var loadIt, local;
local = this;
loadIt = function() {
return calledEarly = true;
};
element.ready(function() {
return loadIt();
});
return {
post: function($scope, element, attributes, controller) {
if (calledEarly) {
return local.link($scope, element, attributes, controller);
}
loadIt = (function($scope, element, attributes, controller) {
return function() {
local.link($scope, element, attributes, controller);
};
})($scope, element, attributes, controller);
}
};
},
link: function($scope, elm, attr, ngModel) {
var ck;
if (!ngModel) {
return;
}
if (calledEarly && !loaded) {
return loaded = true;
}
loaded = false;
ck = CKEDITOR.replace(elm[0]);
ck.on('pasteState', function() {
$scope.$apply(function() {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function(value) {
ck.setData(ngModel.$viewValue);
};
}
};
});
или если вам это нужно в coffeescript
angular.module('ck', []).directive('ckEditor', ->
loaded = false
calledEarly = false
{
require: '?ngModel',
compile: (element, attributes, transclude) ->
local = @
loadIt = ->
calledEarly = true
element.ready ->
loadIt()
post: ($scope, element, attributes, controller) ->
return local.link $scope, element, attributes, controller if calledEarly
loadIt = (($scope, element, attributes, controller) ->
return ->
local.link $scope, element, attributes, controller
)($scope, element, attributes, controller)
link: ($scope, elm, attr, ngModel) ->
return unless ngModel
if (calledEarly and not loaded)
return loaded = true
loaded = false
ck = CKEDITOR.replace(elm[0])
ck.on('pasteState', ->
$scope.$apply( ->
ngModel.$setViewValue(ck.getData())
)
)
ngModel.$render = (value) ->
ck.setData(ngModel.$viewValue)
}
)
Ответ 5
И только для записи, если вы хотите использовать несколько редакторов на одной странице, это может пригодиться:
mainApp.directive('ckEditor', function() {
return {
restrict: 'A', // only activate on element attribute
scope: false,
require: 'ngModel',
controller: function($scope, $element, $attrs) {}, //open for now
link: function($scope, element, attr, ngModel, ngModelCtrl) {
if(!ngModel) return; // do nothing if no ng-model you might want to remove this
element.bind('click', function(){
for(var name in CKEDITOR.instances)
CKEDITOR.instances[name].destroy();
var ck = CKEDITOR.replace(element[0]);
ck.on('instanceReady', function() {
ck.setData(ngModel.$viewValue);
});
ck.on('pasteState', function() {
$scope.$apply(function() {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function(value) {
ck.setData(ngModel.$viewValue);
};
});
}
}
});
Это уничтожит все предыдущие экземпляры ckeditor и создаст новый.
Ответ 6
Теперь есть событие "change", которое можно использовать для этого.
Вот директива, которую я только что создал, которая имеет пару различных параметров конфигурации панели инструментов, я использую адаптер jQuery для инициализации ckeditor. Для получения дополнительной информации просмотрите этот пост в блоге.
(function () {
'use strict';
angular
.module('app')
.directive('wysiwyg', Directive);
function Directive($rootScope) {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModel) {
var editorOptions;
if (attr.wysiwyg === 'minimal') {
// minimal editor
editorOptions = {
height: 100,
toolbar: [
{ name: 'basic', items: ['Bold', 'Italic', 'Underline'] },
{ name: 'links', items: ['Link', 'Unlink'] },
{ name: 'tools', items: ['Maximize'] },
{ name: 'document', items: ['Source'] },
],
removePlugins: 'elementspath',
resize_enabled: false
};
} else {
// regular editor
editorOptions = {
filebrowserImageUploadUrl: $rootScope.globals.apiUrl + '/files/uploadCk',
removeButtons: 'About,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Save,CreateDiv,Language,BidiLtr,BidiRtl,Flash,Iframe,addFile,Styles',
extraPlugins: 'simpleuploads,imagesfromword'
};
}
// enable ckeditor
var ckeditor = element.ckeditor(editorOptions);
// update ngModel on change
ckeditor.editor.on('change', function () {
ngModel.$setViewValue(this.getData());
});
}
};
}
})();
Вот несколько примеров того, как использовать директиву в HTML
<textarea ng-model="vm.article.Body" wysiwyg></textarea>
<textarea ng-model="vm.article.Body" wysiwyg="minimal"></textarea>
И вот сценарии CKEditor, которые я включаю из CDN плюс несколько дополнительных плагинов, которые я загрузил, чтобы включить вставку изображений из слова.
<script src="//cdn.ckeditor.com/4.5.7/full/ckeditor.js"></script>
<script src="//cdn.ckeditor.com/4.5.7/full/adapters/jquery.js"></script>
<script type="text/javascript">
// load extra ckeditor plugins
CKEDITOR.plugins.addExternal('simpleuploads', '/js/ckeditor/plugins/simpleuploads/plugin.js');
CKEDITOR.plugins.addExternal('imagesfromword', '/js/ckeditor/plugins/imagesfromword/plugin.js');
</script>
Ответ 7
Пример ES6 с CKEditor v5.
Укажите директиву, используя:
angular.module('ckeditor', []).directive('ckEditor', CkEditorDirective.create)
Директива:
import CkEditor from "@ckeditor/ckeditor5-build-classic";
export default class CkEditorDirective {
constructor() {
this.restrict = 'A';
this.require = 'ngModel';
}
static create() {
return new CkEditorDirective();
}
link(scope, elem, attr, ngModel) {
CkEditor.create(elem[0]).then((editor) => {
editor.document.on('changesDone', () => {
scope.$apply(() => {
ngModel.$setViewValue(editor.getData());
});
});
ngModel.$render = () => {
editor.setData(ngModel.$modelValue);
};
scope.$on('$destroy', () => {
editor.destroy();
});
})
}
}
Ответ 8
var app = angular.module("CKEditorExample", ["ngCkeditor"]);
app.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);
};
}
};
});
app.controller("MainCtrl", ["$scope", function($scope){
$scope.content = "<p> this is custom directive </p>";
$scope.content_two = "<p> this is ng-ckeditor directive </p>";
}]);
<html ng-app="CKEditorExample">
<head>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<script src="//cdn.ckeditor.com/4.5.6/standard/ckeditor.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="https://s3-ap-southeast-1.amazonaws.com/naveensingh/posts_data/ckeditor_example/ng-ckeditor.min.js"></script>
<title>Angular CKEditor Example with custom directive and ng-ckeditor</title>
</head>
<body ng-controller="MainCtrl" style="padding:20px">
<h1>Method 1</h1>
<textarea ng-model="content" data-ck-editor></textarea>
{{content}}
<hr>
<h1>Method 2</h1>
<textarea ckeditor="editorOptions" ng-model="content_two"></textarea>
{{content_two}}
</body>
</html>