我在 ajax 场景中使用 ckeditor 和 jQuery 适配器。 ckeditor 使用 jQuery 绑定(bind)到 textarea 元素。
应用程序:
我正在为客户设计一个电子学习应用程序。每门类(class)都有许多步骤,这些步骤取自数据库表。
应用程序的 UI 只是一个带有“上一个”和“下一个”按钮的表单,用于在类(class)中导航。
问题在于管理工具,导师可以在其中创建和更新每门类(class)中的步骤。
同样,管理工具只是一个带有上一个和下一个按钮的表单。但是,有一个名为 StepText 的字段,我想要 html 而不是纯文本。因此需要富文本编辑器。
从一个步骤到另一个步骤的滚动是通过 Ajax 调用进行的,该调用会发送到 Controller ,获取下一个(或上一个)步骤的数据,并将其注入(inject)到页面中。 ajax 调用返回从部分 View 创建的 html。
问题:
文本区域在此部分 View 中。第一次加载页面时,CKEditor 会正确绑定(bind),但对于任何后续的 ajax 响应则不会。
结果是 ckEditor 并没有展现出它所有的优点,我只是得到了毫无吸引力的文本区域。
有什么想法为什么会发生这种情况吗?
设置(仅供引用)(已编辑):
使用以下脚本:
<script type="text/javascript" src="@Url.Content("~/ckeditor/ckeditor.js")"></script>
<script type="text/javascript" src="@Url.Content("~/ckeditor/adapters/jquery.js")"></script>
这允许我将 ckEditor 与 jQuery 一起使用,如下所示:
$(document).ready(function () {
$('#StepText').ckeditor(function () { }, { toolbar: 'Basic' });
});
文本区域位于部分 .cshtml 文件中,位于充当 ajax 调用目标的 div 内:
已编辑!展示 ajax 调用是如何进行的!!
<div id="ajaxEditor">
@using (Ajax.BeginForm(MVC.Admin.StepEditor.Edit(), new AjaxOptions { UpdateTargetId = "ajaxEditor", HttpMethod = "POST" },
new { @name = "EditStepForm", @id = "EditStepForm" }))
{
<div class="editor-label">
@Html.LabelFor(model => model.StepText)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.StepText, 20, 68, null)
@Html.ValidationMessageFor(model => model.StepText)
</div>
}
</div>
对克里斯·马里西克的回应:
我尝试在ajax调用的OnSuccess中重新绑定(bind)ckeditor,但是在Chrome中调试jQuery时,出现以下错误:
Uncaught [CKEDITOR.editor] The instance "myTextArea" already exists.
正如您所期望的:控件名称仍然相同,并且没有进行全页刷新。
最佳答案
调用克里斯·马里西克:
如果 Chris Marisic 想要将他的评论升级为答案,我会给他 cookies 。
我已经解决如下:
Ajax 表单:
<div id="ajaxEditor">
@using (Ajax.BeginForm(MVC.Admin.StepEditor.Edit(), new AjaxOptions { UpdateTargetId = "ajaxEditor", HttpMethod = "POST", OnComplete="ReBindCKEditor" },
new { @name = "EditStepForm", @id = "EditStepForm" }))
{
<div class="editor-label">
@Html.LabelFor(model => model.StepText)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.StepText, 20, 68, null)
@Html.ValidationMessageFor(model => model.StepText)
</div>
}
</div>
Javascript:
由于返回的错误(请参阅对相关 Chris Marisic 的回复)表明 CKEDITOR 实例已存在,因此我需要删除它。所以:
function BindCKEditor() {
var elem = $('#StepText');
elem.ckeditor(function () {}, { toolbar: [
['Source'],
['Preview'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Scayt'],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
['Image', 'Table', 'HorizontalRule'],
['Styles', 'Format'],
['Bold', 'Italic', 'Strike'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['Link', 'Unlink', 'Anchor']
]
});
}
BindCKEditor() 只做它所说的事情。它配置编辑器并应用它。
现在,当我用 ajax 响应覆盖文本区域时,我需要删除该实例并重新创建它。所以:
function ReBindCKEditor() {
delete CKEDITOR.instances['StepText'];
BindCKEditor();
}
请注意,我在 Ajax 表单的 OnComplete 中使用 ReBindCKEditor()。我使用 oncomplete 而不是 onsuccess,因为我希望它重新绑定(bind),无论 ajax 调用是否成功。
成功!:
我极力推荐 ckeditor。我以为这将是一个很难解决的噩梦,但是一旦我坐下来把这样的想法放在一边,我发现有非常简洁的文档和很好的用户论坛。
我查看了很多其他富文本编辑器,但没有一个是那么好或得到很好的支持。雅虎的看起来不错,但它是一场噩梦,而且文档很差,除非你是 JavaScript 专家,而我不是。
我几乎选择了 lwrte,它看起来不错,但背后没有支持。
我查看了其他未命名的内容。
但是 ckEditor 确实给我留下了深刻的印象。我现在可以将其推广到我想要的任何地方,无需担心或恐惧。
注意:
我不为 CKEditor 工作,也与他们没有任何联系。这是真正的热情。是的,确实存在这样的事情。
关于jquery - 当 <textarea> 通过 ajax 响应更新时 ckeditor 消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5157732/