Knockoutjs+Ckeditor需要帮助解决一些问题
Knockoutjs + Ckeditor Need help figuring something out
我有这个代码需要与ckeditor:连接
基本上,我想做的是让它通过与已经存在的数据绑定连接
textare-autocomplete="off"class="form control"data bind="rev_ckeditor,value:app.models.userReview.body"id="editor"maxlength="50000"name="body"cols="50"rows="10"
上面的文本区域既有值数据绑定,也有ckeditor的数据dind。但是ckwditor出现了,但没有显示值的数据绑定,有什么问题吗?
代码:
(function($) {
'use strict'
app.viewModels.reviews = {
/**
* All reviews.
*
* @type ko.observable(Array)
*/
sourceItems: ko.observableArray([]),
/**
* Sorting type and order.
*
* @type ko.observable(String)
*/
currentSort: ko.observable(),
/**
* Holds average score of all critic reviews.
*
* @type ko.observable(String)
*/
criticAverage: ko.observable(),
/**
* Holds count of all critic reviews.
*
* @type ko.observable(String)
*/
criticCount: ko.observable(),
/**
* Holds average score of all user reviews.
*
* @type ko.observable(String)
*/
userAverage: ko.observable(),
/**
* Holds count of all user reviews.
*
* @type ko.observable(String)
*/
userCount: ko.observable(),
/**
* Whether to who user, critic or all reviews.
*
* @type ko.observable(String)
*/
currentType: ko.observable(),
/**
* Send request to server to create a new
* user review.
*
* @return void
*/
create: function(form) {
var self = this;
var params = {
data: ko.toJSON(app.models.userReview),
success: function(response) {
var exists = false;
$.each(self.sourceItems(), function(i,v) {
//if user has already written a review for this game we'll just replace
//it with this one as that's what backend is doing as well
if (v.type == 'user' && v.user_id == parseInt(vars.userId)) {
self.sourceItems()[i] = ko.toJS(app.models.userReview);
self.sourceItems.notifySubscribers();
exists = true;
return false;
}
});
if ( ! exists) {
self.sourceItems.push(ko.toJS(app.models.userReview));
}
$('#review-modal').modal('hide');
app.utils.noty(response, 'success');
},
/**
* Append any validation errors returned to new review form.
*
* @param jq
* @return void
*/
error: function(jq) {
$('.alert').remove();
app.utils.appendError(jq);
},
url: form.action,
};
app.utils.ajax(params);
},
/**
* Handle user click on review edit button.
*
* @param app.models.review review
* @return void
*/
edit: function(review) {
app.models.userReview.id(review.id);
app.models.userReview.title(review.title);
app.models.userReview.body(review.body);
app.models.userReview.score(review.score);
app.models.userReview.story_rev(review.story_rev);
app.models.userReview.animation_rev(review.animation_rev);
app.models.userReview.sound_rev(review.sound_rev);
app.models.userReview.characters_rev(review.characters_rev);
app.models.userReview.enjoyment_rev(review.enjoyment_rev);
$('#review-modal').modal('show');
},
/**
* Handle user click on delete button.
*
* @param Object review
* @return void
*/
delete: function(review) {
var self = app.viewModels.reviews;
app.utils.ajax({
url: vars.urls.baseUrl+'/movies/'+vars.titleId+'/reviews/'+review.id,
type: 'DELETE',
data: ko.toJSON(vars.token),
success: function() {
self.sourceItems.remove(review);
}
})
}
};
/**
* Calculate average critic/user review score as well as review counts.
*
* @return void
*/
app.viewModels.reviews.calculateMeta = ko.computed(function() {
var self = this, score = 0,
crCount = 0, crAvg = 0,
uCount = 0, uAvg = 0;
$.each(self.sourceItems(), function(ind, val) {
if (val.type == 'critic') {
crCount++;
crAvg += parseFloat(val.score);
} else if (val.type == 'user') {
uCount++;
uAvg += parseFloat(val.score);
}
});
//set average to flash if there's no reviews otherwise calculate an avarage
crCount ? self.criticAverage(crAvg / crCount) : self.criticAverage('/');
uCount ? self.userAverage(uAvg / uCount) : self.userAverage('/');
self.userCount(uCount);
self.criticCount(crCount);
}, app.viewModels.reviews, {deferEvaluation: true});
/**
* Filters critic reviews on platform dropdown change,
* if no reviews found fires an ajax request to query
* review data provider.
*
* @return array
*/
app.viewModels.reviews.filteredReviews = ko.computed(function() {
var self = this, filtered;
//filter by user or critic reviews if user select either
if (self.currentType() === 'all') {
filtered = self.sourceItems();
} else {
filtered = ko.utils.arrayFilter(self.sourceItems(), function(rev) {
return rev.type === self.currentType();
});
}
//split current sort by camelCase into type and order params
var sort = self.currentSort().match(/([A-Z]?[^A-Z]*)/g).slice(0,-1);
if (sort.length === 2) {
filtered.sort(app.utils.sort[sort[0]](sort[1]));
}
return filtered ? filtered : [];
}, app.viewModels.reviews, {deferEvaluation: true});
/**
* New review form model.
*
* @type Object
*/
app.models.userReview = {
id: ko.observable(),
author: app.username,
title: ko.observable(),
source: 'Test',
body: ko.observable(),
story_rev: ko.observable(),
animation_rev: ko.observable(),
characters_rev: ko.observable(),
sound_rev: ko.observable(),
enjoyment_rev: ko.observable(),
score: ko.observable(),
type: 'user',
_token: vars.token,
user_id: app.user_id,
};
/**
* Renders CKeditor on textarea.
*
* @type {Object}
*/
ko.bindingHandlers.rev_ckeditor = {
init: function (element, valueAccessor, allBindingsAccessor, context, review) {
var $element = $(element);
var value = ko.utils.unwrapObservable(valueAccessor());
$element.html(value);
var editor = CKEDITOR.replace('editor');
/**
* Resize CKeditor according to textarea col and rows attributes.
*
* @return void
*/
jQuery.fn.cke_resize = function() {
return this.each(function() {
var $this = $(this);
var rows = $this.attr('rows');
var height = rows * 20;
$this.next("div.cke").find(".cke_contents").css("height", height);
});
};
CKEDITOR.on('instanceReady', function(){ $element.cke_resize(); });
//Update body observable on ckeditor blur event
editor.on('blur', function (e) {
var obs = app.models.userReview.body(review.body);
if (ko.isWriteableObservable(obs)) {
obs(e.editor.getData());
}
});
}
};
})(jQuery);
我不熟悉CKEditor,所以我在这里可能错了,但许多所见即所得编辑器不会因为您更改了底层<textarea>
中的数据而自行更新,而value
绑定就是这样做的。我建议完全删除value
绑定,让编辑器绑定到所有工作中。
现在,您的绑定似乎只处理编写编辑器对可观察对象的更改。我们还需要处理相反的方向,并将可观察到的更改写入编辑器。根据CKEditor文档,这是通过编辑器#setData:完成的
ko.bindingHandlers.rev_ckeditor = {
init: function (element, valueAccessor, allBindingsAccessor, context, review) {
var $element = $(element),
observable = valueAccessor();
var editor = CKEDITOR.replace('editor');
ko.computed(function() {
editor.setData( observable() );
}, { disposeWhenNodeIsRemoved: element });
jQuery.fn.cke_resize = function () {
return this.each(function () {
var $this = $(this);
var rows = $this.attr('rows');
var height = rows * 20;
$this.next("div.cke").find(".cke_contents").css("height", height);
});
};
CKEDITOR.on('instanceReady', function () {
$element.cke_resize();
});
editor.on('blur', function (e) {
if (ko.isWriteableObservable(observable)) {
observable(e.editor.getData());
}
});
}
};
通常,会将对可观察到的更改写回绑定update
处理程序中的编辑器。在这种情况下,在init
处理程序中执行更方便,因为我们已经可以访问那里的编辑器实例。
如果您允许编辑器绑定访问可观察对象,那么一切都应该按预期工作:
<textarea data-bind="rev_ckeditor: app.models.userReview.body"></textarea>
相关文章:
- 如何解决Yii中的页面刷新问题
- 简单的ES6承诺问题-交换解决和拒绝参数
- 为什么不'我的窗口滚动事件根本没有启动.其他答案没有解决问题
- jQuery通过步骤的自排队循环来解决延迟问题
- 我该如何解决这个问题?“未捕获的类型错误:无法读取 null 的属性'appendChild'”
- MathJax正在复制我的方程式——为什么以及如何解决这个问题
- JS驱动的常见问题页面的推荐DB解决方案
- 如何解决youtube播放器没有显示全宽的问题&身高
- 我该如何解决这个问题;参考网格”;在JavaScript中完成的对象数
- 在我的案例中,如何解决我的承诺问题
- 解决从 1.0.5 升级到 angularjs 1.3 时出现的问题
- Google 日历 API V3 会解决与会者和创建者 Java 脚本问题
- 如何在窗体中使用多个按钮解决验证问题
- 当服务器从 http 更改为 https 时,有哪些可能的方法可以解决问题
- .attr(“href”) 的问题!解决此问题的简单方法
- 你能帮忙解决这个逻辑问题吗?
- 如何在 JavaScript for D3.js 中解决这样的范围问题
- TypeError:$(..).higharts不是函数-现有解决方案不起作用-Yeoman生成器存在问题
- 投票系统大拇指向上和向下的问题解决
- Iframe滚动问题.解决方案是什么