4

我正在使用这个很棒的编辑器,但我不知道如何将内容绑定到淘汰赛:

http://imperavi.com/redactor/

4

4 回答 4

4

这是一个完成这项工作的双向绑定处理程序。与此类处理程序一样,该update函数将更改从 VM 传递到 UI 元素(Redactor 元素),init并将更改从 Redactor 传递回 VM。

当我发布此内容时,它是为 Redactor 9 发布的,我现在已经为 Redactor 10 更新了它。

ko.bindingHandlers.redactor = {

    init: function(element, valueAccessor) {

        var value = valueAccessor();

        // We only want Redactor to notify our value of changes if the value
        // is an observable (rather than a string, say).

        if (ko.isObservable(value)) {
            $(element).redactor({
                changeCallback: value
            });
        }

    },

    update: function(element, valueAccessor) {

        // New value, note that Redactor expects the argument passed to 'set'
        // to have toString method, which is why we disjoin with ''.

        var value = ko.utils.unwrapObservable(valueAccessor()) || '';

        // We only call 'set' if the content has changed, as we only need to
        // to do so then, and 'set' also resets the cursor position, which
        // we don't want happening all the time.

        // This code would work with Redactor 9, but no longer works with Redactor 10
        //if (value !== $(element).redactor('get')) {
        //    $(element).redactor('set', value);
        //}

        // The API method has become 'code.get', and it behaves a bit differently: it
        // returns formatted HTML, i.e. with whitespace and EOLs.  That means that we
        // would update the Redactor content every time the observable changed, which
        // was bad.  So instead we can use this:
        if (value !== $(element).redactor('core.getTextarea').val()) {
            $(element).redactor('code.set', value );
        }
   }

}

如果要使用 Redactor 编辑的内容的 KO observable 是,content那么您可以执行以下操作:

<textarea data-bind="redactor: content"></textarea>

要使上述内容与 Redactor 10 一起使用,您必须进行一些更改。首先,您必须使用“code.set”和“code.get”,而不是简单的“set”和“get”来与 HTML 交互。但是如果你只这样做,你会发现'code.get'返回的HTML

于 2013-12-18T00:23:14.620 回答
1

我不知道它是否正确,但这段代码对我有用:

创建新的绑定处理程序:

    ko.bindingHandlers.imperavi =
    {
            init: function(element, valueAccessor, allBindings)
            {
                var startValue = allBindings().value();
                var $el = $(element);
                $el.val(startValue).change();
                $el.redactor({
                    changeCallback: function(html)
                    {
                        $el.val(html).change();
                    }
                });
            }
    };

在 HTML 中:

<textarea data-bind="value: Text, imperavi: true"></textarea>

视图模型:

var VM = function()
{
    this.Text = ko.observable('<p>Hello world</p>');
};

var vm = new VM();
ko.applyBindings(vm);
于 2013-09-21T11:16:45.840 回答
1

我已经更新了 dvijaz 的 Redactor 10 版本以支持新的 Redactor 2 版本(感谢 dvijaz!):

ko.bindingHandlers.redactor = {

init: function(element, valueAccessor) {

    var value = valueAccessor();

    // We only want Redactor to notify our value of changes if the value
    // is an observable (rather than a string, say).

    if (ko.isObservable(value)) {
        $(element).redactor({ callbacks: { change: value } });
    }

},

update: function(element, valueAccessor) {

    // New value, note that Redactor expects the argument passed to 'set'
    // to have toString method, which is why we disjoin with ''.

    var value = ko.utils.unwrapObservable(valueAccessor()) || '';

    // We only call 'set' if the content has changed, as we only need to
    // to do so then, and 'set' also resets the cursor position, which
    // we don't want happening all the time.

    // This code would work with Redactor 9, but no longer works with Redactor 10
    //if (value !== $(element).redactor('get')) {
    //    $(element).redactor('set', value);
    //}

    // The API method has become 'code.get', and it behaves a bit differently: it
    // returns formatted HTML, i.e. with whitespace and EOLs.  That means that we
    // would update the Redactor content every time the observable changed, which
    // was bad.  So instead we can use this:
    if (value !== $(element).redactor('core.textarea').val()) {
        $(element).redactor('code.set', value);
    }

} }

于 2015-12-07T18:37:54.947 回答
0

我喜欢我应该能够相互独立地使用 knockoutjs 和 redactorjs 的想法。当 redactorjs 更新 textarea 时,knockoutjs 应该接管并通过它的绑定更新模型。

我发现当 textarea 更改时 redactorjs 没有传播更改事件。为了解决这个问题,我手动添加了它:

$('textarea').each(function() {
  var textareaEl = $(this);
  textareaEl.redactor({
    blurCallback: function() {
      textareaEl.change();
    }
  });
});

这里还有改进的余地,因为这似乎在每个关键事件上都会触发 changeCallback。 但是这个解决方案有效并且不会使 redactorjs 成为您的 knockoutjs 应用程序中的依赖项(或在 redactor 版本更改时中断)。

编辑:我在 redactorjs 的源代码中发现了一个未记录的 blurCallback。替换了似乎在 keyUp 上触发的 changeCallback 的使用。

于 2015-09-29T18:48:53.420 回答