TinyMce在SPA中消失 - Knockout绑定评估两次导致编辑器失败

时间:2014-06-09 01:33:07

标签: knockout.js binding tinymce durandal tinymce-4

我正在尝试将 TinyMCE 实施到John Papa的 HotSpa模板中。

我目前正在使用 Knockout 3.1.0 Durandal 2.0

由于某些未知原因,我的自定义knockout绑定init方法仅在第一次加载时触发一次,但在刷新视图时触发两次。

通过刷新,我的意思是使用durandal路由器,我再次导航到相同的视图(但使用不同的参数)。它仍然经历了整个durandal生命周期,脱离和附着的钩子再次被召唤。

我有一些调试代码,其中第二个调用返回.editors.length = 1,这意味着编辑器已在第一次调用中初始化。

注意:在init方法中我有一个方法ko.utils.domNodeDisposal.addDisposeCallback,由于某种原因,它在第二次init调用后被调用。我评论了它, tinyMCE 仍然消失了。我浏览编辑,发现它被认为是隐藏的。 isHdidden = true

<textarea id="mytinymce" class="tinymce" 
          data-bind="attr: {id: FieldId}, tinymce: FieldValue”></textarea>

页面最初使用TinyMCE控件正确加载,但在屏幕刷新后失败。

我远离视线,然后返回。

ko.bindingHandlers.tinymce = {
        init: function (element, valueAccessor, allBindingsAccessor, 
                        context, arg1, arg2) {
            var options = allBindingsAccessor().tinymceOptions || {};
            var modelValue = valueAccessor();
            var value = ko.utils.unwrapObservable(valueAccessor());

            var el = $(element);
            var id = el.attr('id');

            //options.theme = "advanced";
            options.theme = "modern";

            options.menubar = false;
            options.plugins = [
                "advlist autolink autosave link image lists charmap print preview hr anchor pagebreak spellchecker",
                "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
                "table contextmenu directionality template textcolor paste fullpage textcolor"
            ];
            //tinymce buttons
            //http://www.tinymce.com/tryit/classic.php
            options.toolbar_items_size = 'small';
            options.toolbar1 =
            "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | forecolor backcolor | hr removeformat | subscript superscript  ";

            ////handle edits made in the editor. Updates after an undo point is reached.
            options.setup = function (editor) {
                editor.on('change', function (e) {
                    if (ko.isWriteableObservable(modelValue)) {
                        var content = editor.getContent({ format: 'raw' });
                        modelValue(content);
                    }
                });

            };

            el.html(value);

            $(element).tinymce(options);

            //handle disposal (if KO removes by the template binding)
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                var tinymceInstance = tinyMCE.get(id);
                if (tinymceInstance != undefined) {
                    // if instance already exist, then get rid of it... we don't want it
                    tinymceInstance.remove();
                }
            });              
        },
        update: function (element, valueAccessor, allBindingsAccessor, 
                          context) {

            var el = $(element);
            var value = ko.utils.unwrapObservable(valueAccessor());
            var id = el.attr('id');

            //handle programmatic updates to the observable
            // also makes sure it doesn't update it if it's the same. 
            // otherwise, it will reload the instance, causing the cursor to jump.
            if (id !== undefined) {
                //$(el).tinymce();

                var tinymceInstance = tinyMCE.get(id);
                if (!tinymceInstance)
                    return;
                var content = tinymceInstance.getContent({ format: 'raw' });
                if (content !== value) {
                    //tinymceInstance.setContent(value);
                    valueAccessor(content);
                    //$(el).html(value);
                }
            }
        }
    };

不幸的是,我没有在控制台中看到任何错误,但编辑器(包括文本区域)是隐藏的,不可见。

2 个答案:

答案 0 :(得分:1)

我已将html更改为:

<textarea data-bind="tinymce: FieldValue"></textarea>

即。删除了id属性绑定。

现在它有效。

我注意到它仍然会调用init两次,但它有效。

您必须让TinyMCE控制ID。

答案 1 :(得分:0)

您说您两次输入init功能。

您是否尝试过一个简单的代码以防止第二次运行其代码? (如果你有一个工作的jsFiddle,我会尝试)

类似的东西:

ko.bindingHandlers.tinymce = {
    init: function (element, valueAccessor, allBindingsAccessor, 
                    context, arg1, arg2) {
        if (!$(element).data("tinymce-hasinitstarted")) {
            $(element).data("tinymce-hasinitstarted", true);
            //your code here
        }
    }
}