簡體   English   中英

在Knockout中使用ckeditor作為observableArray的一部分

[英]Using ckeditor in Knockout as part of an observableArray

我正在嘗試使用CKeditor和剔除將RTF編輯器添加到我的測量系統中。 我有ViewModel,它有一個可觀察的問題數組。 我想使每個問題中的名稱都使用ckeditor。 我看過自定義綁定中的Knockout.js:array參數 並且實現了,但是我的OnBlur無法正常工作。 ValueAccessor()不返回可觀察對象。 所以我得到一個錯誤,即在該行代碼中字符串不是function()。

  var observable = valueAccessor();
  observable($(element).val());

這是我的HTML,我現在使用的是靜態ID,在將其用於數組中的一個問題后,將對其進行更改。

<tbody data-bind="foreach: questionModel">
                                    <tr>
                                        <td>
                                            <button data-bind='click: $root.addQuestion' class="btn btn-success" title="Add Question"><i class="icon-plus-sign fontColorWhite"></i></button>
                                            <button data-bind='click: $root.removeQuestion' class="btn btn-danger" title="Remove Question"><i class="icon-minus-sign fontColorWhite"></i></button>
                                        </td>
                                        <td><textarea id="question123" class="RichText" data-bind="richText: Name"></textarea></td>
                                        <td><input type="checkbox" data-bind="checked: AllowComment"  /></td>
                                        <td><button data-bind="click: $root.addAnswer" class="btn btn-success" title="Add Answer"><i class="icon-plus-sign fontColorWhite"></i></button></td>
                                        <td>
                                            <div  data-bind="foreach: possibleAnswerModel">
                                                <input style="width: 278px"  style="margin-bottom: 5px;" data-bind='value: Name' />
                                                 <button data-bind='click: $root.removeAnswer' class="btn btn-danger" title="Remove Answer"><i class="icon-minus-sign fontColorWhite"></i></button>
                                            </div>
                                        </td>
                                    </tr>
                                    <tr>
                                </tbody>

下面是我的ViewModel以及我的自定義綁定。

ko.bindingHandlers.richText = {
        init: function (element, valueAccessor, allBindingsAccessor, ViewModel) {

            var txtBoxID = $(element).attr("id");

            console.log("TextBoxId: " + txtBoxID);

            var options = allBindingsAccessor().richTextOptions || {};

            options.toolbar_Full = [
                ['Bold', 'Italic'],
                ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'],
                ['Link', 'Unlink']
            ];
            //handle disposal (if KO removes by the template binding)

            ko.utils.domNodeDisposal.addDisposeCallback(element, function() {

                if (CKEDITOR.instances[txtBoxID]) {
                    CKEDITOR.remove(CKEDITOR.instances[txtBoxID]);
                };
            });

            $(element).ckeditor(options);

            //wire up the blur event to ensure our observable is properly updated

            CKEDITOR.instances[txtBoxID].focusManager.blur = function () {
                console.log("blur");
                console.log("Value: " + valueAccessor());
                console.log("Value: " + $(element).val());

                var observable = valueAccessor();
                observable($(element).val());

           };
        },

        update: function (element, valueAccessor, allBindingsAccessor, ViewModel) {
            var value = valueAccessor();

            console.log("Value Accessor: " + value);

            var valueUnwrapped = ko.utils.unwrapObservable(value);

            //var val = ko.utils.unwrapObservable(valueAccessor());
            console.log("Value: " + valueUnwrapped);
            $(element).val(valueUnwrapped);
        }
    };

function ViewModel(survey) {
        // Data
        var self = this;

        self.StartDate = ko.observable(survey.StartDate).extend({ required: { message: 'Start Date is required' } });
        self.EndDate = ko.observable(survey.EndDate).extend({ required: { message: 'End Date is required' } });
        self.Name = ko.observable(survey.Name).extend({ required: { message: 'Name is required' } });
        self.ButtonLock = ko.observable(true);

        self.questionModel = ko.observableArray(ko.utils.arrayMap(survey.questionModel, function(question) {
            return { Id: question.QuestionId, Name: ko.observable(question.Name), Sort: question.Sort, IsActive: question.IsActive, AllowComment: question.AllowComment, possibleAnswerModel: ko.observableArray(question.possibleAnswerModel) };
        }));

        // Operations
        self.addQuestion = function () {
            self.questionModel.push({
                Id: "0",
                Name: "",
                AllowComment: true,
                Sort: self.questionModel().length + 1,
                possibleAnswerModel: ko.observableArray(),
                IsActive:true
            });
        };

        self.addAnswer = function (question) {
            question.possibleAnswerModel.push({
                Id: "0",
                Name: "",
                Sort: question.possibleAnswerModel().length + 1,
                IsActive:true
            });
        };

        self.GetBallotById = function (id) {
            for (var c = 0; c < self.BallotProjectStandardList().length; c++) {
                if (self.BallotProjectStandardList()[c].BallotId === id) {
                    return self.BallotProjectStandardList()[c];
                }
            }
            return null;
        };

        self.removeQuestion = function(question) { self.questionModel.remove(question); };

        self.removeAnswer = function(possibleAnswer) { $.each(self.questionModel(), function() { this.possibleAnswerModel.remove(possibleAnswer) }) };

        self.save = function() {
            if (self.errors().length == 0) {
                self.ButtonLock(true);
                $.ajax("@Url.Content("~/Survey/Create/")", {
                    data: ko.toJSON(self),
                    type: "post",
                    contentType: 'application/json',
                    dataType: 'json',
                    success: function(data) { self.successHandler(data, data.success); },
                    error: function() {
                        self.ButtonLock(true);
                        self.errorHandler();
                    }
                });
            } else {
                self.errors.showAllMessages();
            }
        };
    }

    ViewModel.prototype = new ErrorHandlingViewModel();
    var mainViewModel = new ViewModel(@Html.Raw(jsonData));
    mainViewModel.errors = ko.validation.group(mainViewModel);
    ko.applyBindings(mainViewModel);

我發現自己做錯了。 當我定義observableArray()時,我將對象定義為ko.observable,但是,當我向數組中添加問題時,我將其初始化為字符串。 因此,我將其更改為與之匹配,並且像冠軍一樣工作。 這是變革的推動力。

     self.questionModel = ko.observableArray(ko.utils.arrayMap(survey.questionModel, function(question) {
            return { Id: question.QuestionId, Name: ko.observable(question.Name), Sort: question.Sort, IsActive: question.IsActive, AllowComment: question.AllowComment, possibleAnswerModel: ko.observableArray(question.possibleAnswerModel) };
        }));

        // Operations
        self.addQuestion = function () {
            self.questionModel.push({
                Id: "0",
                Name: ko.observable(),
                AllowComment: true,
                Sort: self.questionModel().length + 1,
                possibleAnswerModel: ko.observableArray(),
                IsActive:true
            });
        }; 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM