我有這樣的代碼,我需要用的CKEditor連接:Knockoutjs + CKEDITOR需要幫助您計算出來的東西
基本上我試圖做的是把它與數據綁定的是已經存在通過連接:
textarea autocomplete="off" class="form-control" data-bind="rev_ckeditor, value: app.models.userReview.body" id="editor" maxlength="50000" name="body" cols="50" rows="10"
上面的textarea同時具有值data-bind和ckeditor的data-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);
你能在小提琴重現? – firstdoit 2015-03-03 10:23:14