Summernote + Knockoutjs编辑器在更新observable值后未更新

时间:2017-03-15 17:27:22

标签: javascript knockout.js summernote

我有像这样的夏令营的knockoutjs自定义绑定:

<script>
        ko.bindingHandlers.summernote = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var value = ko.unwrap(valueAccessor());
                var $element = $(element);
                $element.html(value).summernote({
                    onChange: function (contents) {
                        valueAccessor()(contents);
                    }
                });
            },
            update: function (element, valueAccessor) {
                var $element = $(element);
                $element.summernote('code',ko.utils.unwrapObservable(valueAccessor()));

            }
        };
    </script>

<div class="html-editor" data-bind="summernote: PublishNote"></div>

self.PublishNote = ko.observable();

任何工作正常,但不是来自js的更新可观察值。 如果我初始化self.PublishNote = ko.observable('Hello');。但如果我将可观察变量更新为self.PublishNote('<h1>Hello World</h1')。编辑未更新。

请帮助我们完成这个ko-summernote 所以它可以像这样从js代码更新编辑器 self.PublishNote('<h1>Hello World</h1')

var ViewModel = function () {
            var self = this;
            self.Id = '1';
            self.PublishNote = ko.observable('initial value');
            setTimeout(function(){
              self.PublishNote('<h1>Hello World</h1'); //not work
            }, 1000);

            self.Submit = function () {
                var dataToSend = {
                    PublishNote: self.PublishNote())
                };
                $.post('@Url.Action("Edit")', dataToSend)
                .success(function (res) {
                    console.log(res);
                })
                .fail(function (err) {
                    console.log(err);
                })
            }

            self.Init = function () {
                $.post('@Url.Action("InitEdit")', {
                    id: self.Id
                })
                .success(function (res) {
                    self.PublishNote(res); //not work
                })
                .fail(function (err) {
                    console.log(err);
                })
            }
        }
        var vm = new ViewModel();
        ko.applyBindings(vm);
        vm.Init();

<div class="html-editor" data-bind="summernote: PublishNote"></div>

1 个答案:

答案 0 :(得分:2)

通常,自定义绑定使用配置选项作为参数来初始化封装的插件(在本例中为summernote)。

在示例中,参数allBindingsAccessor用于获取summernote的配置对象,该对象将高度设置为300px(如果不需要自定义配置,则使用true)。回调是在'summernote.change'事件中注册的。此回调使用allBindings参数来访问'value'绑定中使用的observable并更新其值。

这样,您可以根据需要删除绑定来打开/关闭绑定,并且值observable仍然有效。您可以通过单击编辑器底部的按钮来检查observable中的当前值。

ko.bindingHandlers.summernote = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var allBindings = allBindingsAccessor();

        // initialize summernote with config from binding
        var summernoteConfig = ko.utils.unwrapObservable(allBindings.summernote);
        summernoteConfig = (typeof summernoteConfig === 'object') ? summernoteConfig : {}
        $(element).summernote(summernoteConfig);
        $(element).summernote('code', allBindings.value());

        // callback to update value observable
        $(element).on('summernote.change',  function(we, contents, $editable) {
            allBindings.value(contents);
        });
    }
};

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

    self.PublishNote = ko.observable("INITIAL CONTENTS");
    self.ShowContents = function() {
        alert(self.PublishNote());
    }
};

ko.applyBindings(new ViewModel());
<!-- include libraries(jQuery, bootstrap) -->
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>

<!-- include summernote css/js-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.js"></script>

<!-- knockout -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"type="text/javascript"></script>

<!-- HTML -->
<div class="html-editor" data-bind="value: PublishNote, summernote: { height: 300 }"></div>
<button data-bind="click: ShowContents">Show Contents</button>