如何在 Durandal 中使用 TinyMCE(Knockout,RequireJS)

How to use TinyMCE in Durandal (Knockout, RequireJS)

我从几个小时开始就尝试在我的 SPA 中获取 TinyMCE 运行。我已经找到了一些答案,但对我不起作用。

例如这个 JSFiddle http://jsfiddle.net/scottmessinger/yJ5GV/2/;

他们更多的是关于如何绑定数据,而不是如何启动 TinyMCE^^ 如果我将脚本放在 index.html 中并在 index.html 中调用它 "textarea" 是查看结果的唯一途径。

Main.js(加载tinymce脚本)

requirejs.config({
 paths: {
    'text': '../lib/require/text',
    'durandal':'../lib/durandal/js',
    'plugins' : '../lib/durandal/js/plugins',
    'transitions' : '../lib/durandal/js/transitions',
    'knockout': '../lib/knockout/knockout-3.1.0',
    'jquery': '../lib/jquery/jquery-1.9.1',
    'bootstrap': '../lib/bootstrap/js/bootstrap',
    'lodash': '../lib/lodash/lodash',
    'jqueryUI': '../lib/jquery/jquery-ui.min',
    'tinymce': '../lib/tinymce/tinymce.min',
    'tinymceJquery': '../lib/tinymce/jquery.tinymce.min'
},
shim: {
    'jquery': {
        exports: '$'
    },
    'bootstrap': {
        deps: ['jquery'],
        exports: 'jQuery'
   }
}
});

Verwaltung.js

define([
'services/accountrepository',
'plugins/router',
'services/blogrepository',
'durandal/app',
], function (accountrepository, router, blogrepository, app) {

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);
            }
        }
    }

};

var viewmodel = function () {
     var self = this;

    self.fieldValue = ko.observable("two");

 };
return viewmodel;
});

Verwaltung.html

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

理论上这应该可以工作,因为只有在加载 DOM 并且元素准备就绪后,Knockout 才会构建此视图,但是 Durandal 对此可能有点挑剔。 Durandal 确实有一些事件可以用来加载这个插件。 就个人而言,我会将所有这些代码从 Knockout 扩展中取出,并将其放在 Durandal ViewModel 或 Widget 中。 使用一个模型,你可以连接到 compositionComplete 事件中,我会调用初始化 TinyMCE 插件,但是如果你想将它组合成多个视图,那么这很困难,因为父级必须调用它,因为组合不会得到生命循环事件。 如果你想组成多个视图,那么你可以使用 Durandal 小部件。

http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html http://durandaljs.com/documentation/Creating-A-Widget

我认为在尝试加载插件之前,您可能需要掌握创建 Views/viewmodel、小部件和组合的方法。只是为了让您了解框架的这些核心领域。 Durandal 是一个很棒的工具,请坚持使用!