Knockout js中的单选按钮双向绑定与自定义绑定获取错误,因为observable不是一个函数

问题描述 投票:-1回答:1

JSON数据

    [
    {
        "ErrorCode": 0,
        "ErrorMessage": null,
        "Heading": "Assessment",
        "SectionsSet": [
            {
                "ErrorCode": 0,
                "ErrorMessage": null,
                "Heading": "Assessment",
                "SectionsSet": [],
                "QuestionsSet": [
                    {
                        "ErrorCode": 0,
                        "ErrorMessage": null,
                        "Available": true,
                        "DisplayValue": "Q1",
                        "QuestionText": "What is the status of an advance care planning assessment?",
                        "TopLevel": true,
                        "Type": 1,
                        "AnswersSet": [
                            {
                                "ErrorCode": 0,
                                "ErrorMessage": null,
                                "Available": true,
                                "InputType": "text",
                                "Value": null,
                                "Text": "Advance care planning information has already been provided:",
                                "MutuallyExclusive": false,
                                "Selected": false,
                                "QuestionRefSet": [],
                                "GuidelineLinkSet": [],
                                "ChildQuestions": null,
                                "QuestionRefSetStrings": "",
                                "RadioOnly": true,
                                "HtmlText": "Advance care planning information has already been provided:",
                                "AnnotationSet": [],
                                "CitationSet": [],
                                "FootnoteSet": [],
                                "Id": "406",
                                "SortOrder": 1,
                                "Uid": "s/Assessment1-s78832-q1954-a406"
                            },
                            {
                                "ErrorCode": 0,
                                "ErrorMessage": null,
                                "Available": true,
                                "InputType": "text",
                                "Value": null,
                                "Text": "Advance care planning assessment is scheduled for a later date:",
                                "MutuallyExclusive": false,
                                "Selected": false,
                                "QuestionRefSet": [],
                                "GuidelineLinkSet": [],
                                "ChildQuestions": null,
                                "QuestionRefSetStrings": "",
                                "RadioOnly": true,
                                "HtmlText": "Advance care planning assessment is scheduled for a later date:",
                                "AnnotationSet": [],
                                "CitationSet": [],
                                "FootnoteSet": [],
                                "Id": "407",
                                "SortOrder": 2,
                                "Uid": "s/Assessment1-s78832-q1954-a407"
                            },
                            {
                                "ErrorCode": 0,
                                "ErrorMessage": null,
                                "Available": true,
                                "InputType": "text",
                                "Value": null,
                                "Text": "Not appropriate to conduct advance care planning assessment with person reachable today:",
                                "MutuallyExclusive": false,
                                "Selected": false,
                                "QuestionRefSet": [],
                                "GuidelineLinkSet": [],
                                "ChildQuestions": null,
                                "QuestionRefSetStrings": "",
                                "RadioOnly": true,
                                "HtmlText": "Not appropriate to conduct advance care planning assessment with person reachable today:",
                                "AnnotationSet": [],
                                "CitationSet": [],
                                "FootnoteSet": [],
                                "Id": "408",
                                "SortOrder": 3,
                                "Uid": "s/Assessment1-s78832-q1954-a408"
                            },
                            {
                                "ErrorCode": 0,
                                "ErrorMessage": null,
                                "Available": true,
                                "InputType": "text",
                                "Value": null,
                                "Text": "Other:",
                                "MutuallyExclusive": false,
                                "Selected": false,
                                "QuestionRefSet": [],
                                "GuidelineLinkSet": [],
                                "ChildQuestions": null,
                                "QuestionRefSetStrings": "",
                                "RadioOnly": true,
                                "HtmlText": "Other:",
                                "AnnotationSet": [],
                                "CitationSet": [],
                                "FootnoteSet": [],
                                "Id": "1917",
                                "SortOrder": 4,
                                "Uid": "s/Assessment1-s78832-q1954-a1917"
                            },
                            {
                                "ErrorCode": 0,
                                "ErrorMessage": null,
                                "Available": true,
                                "InputType": null,
                                "Value": null,
                                "Text": "Don't know/Not sure",
                                "MutuallyExclusive": false,
                                "Selected": false,
                                "QuestionRefSet": [],
                                "GuidelineLinkSet": [],
                                "ChildQuestions": null,
                                "QuestionRefSetStrings": "",
                                "RadioOnly": true,
                                "HtmlText": "Don't know/Not sure",
                                "AnnotationSet": [],
                                "CitationSet": [],
                                "FootnoteSet": [],
                                "Id": "6",
                                "SortOrder": 5,
                                "Uid": "s/Assessment1-s78832-q1954-a6"
                            }
                        ],
                        "QuestionReferencesSet": null,
                        "ChildQuestions": null,
                        "HtmlText": "What is the status of an advance care planning assessment?",
                        "AnnotationSet": [],
                        "CitationSet": [],
                        "FootnoteSet": [],
                        "Id": "1954",
                        "SortOrder": 1,
                        "Uid": "s/Assessment1-s78832-q1954"
                    }
]

用于单选按钮的HTML代码,其中trueFalseRadioButton是自定义绑定。 $data.Selected是包含frue / false的值,$data.RadioOnly的值为true / false。

<!-- language: lang-html -->

<div data-bind="foreach: GuidelinesSubmitList">
        <div data-bind="foreach: $data.SectionsSet">
            <div data-bind="foreach: $data.SectionsSet">
                <div>
                    <p class="primaryCaseHeader" data-bind="attr:{onClick: 'variableName.CollapseExpandCustom.ToggleSection(\''+$data.Id+'\')'}">
                        <span data-bind="text: $root.SplitGuidelinesQuestionHeading() + '- '+ $data.Heading"></span><img src="/Images/Collapse.png">
                    </p>
                    <div>
                        <div class="primaryCaseMain" data-bind="attr:{id:$data.Id}">
                            <div data-bind="foreach: $data.QuestionsSet">
                                <div class="primaryCaseContainer" data-bind="attr: {id: $data.Id } , visible: $data.Available, toplevel: $data.TopLevel">
                                    <p class="questionHeader">
                                        <span data-bind="text: $data.DisplayValue+'.'"></span>
                                        <span data-bind="html: GetEditListGuidelineQuestion.HtmlReplace($data.HtmlText)"></span>
                                    </p>
                                    <div data-bind="attr:{id: 'colapseID'+$data.Id }" class="questionContainer">

                                        <div data-bind="foreach: $data.AnswersSet">

                                            <!--ko if:$parent.Type == 2 -->
                                            <div data-bind="attr:{class: $parent.Id +' marginTopTbl'}">
                                                <input type="checkbox" data-bind="attr:{id: $data.Id , Qid: $parent.Id , Qref: $data.QuestionRefSetStrings , Uid: $data.Uid , rel: $data.MutuallyExclusive ? 'true' : 'false'} ,checked: $data.Selected, click: $root.answerClick , if: $root.appendQrefQuestion($data.QuestionRefSetStrings)">
                                                <span data-bind="html: GetEditListGuidelineQuestion.HtmlReplace($data.HtmlText)"></span>
                                                <span><b data-bind="text: $root.findQuestionref($data.QuestionRefSet)"></b></span>
                                                <!--ko if:$data.InputType == "text" -->
                                                <input type="text" data-bind="if: Selected, textInput : $data.Value, attr:{id: $data.Id , name:$parent.Id,  Qid: $parent.Id, Qref: $data.QuestionRefSetStrings , Uid: $data.Uid}">
                                                <!-- /ko -->
                                            </div>
                                            <!-- /ko -->
                                            <!--ko if:$parent.Type == 1 -->
                                            <div data-bind="attr:{class: $parent.Id +' marginTopTbl'}">
                                                <input type="radio" data-bind="value: $data.RadioOnly, attr:{id: $data.Id , name:$parent.Id,  Qid: $parent.Id, Qref: $data.QuestionRefSetStrings , Uid: $data.Uid},  trueFalseRadioButton:  $data.Selected , click: $root.answerClick , if: $root.appendQrefQuestion($data.QuestionRefSetStrings)">
                                                <span data-bind="html: GetEditListGuidelineQuestion.HtmlReplace($data.HtmlText)"></span>
                                                <span><b data-bind="text: $root.findQuestionref($data.QuestionRefSet)"></b></span>
                                                <!--ko if:$data.InputType == "text" -->
                                                <input type="text" data-bind="if: Selected , textInput: $data.Value , attr:{id: $data.Id , name:$parent.Id,  Qid: $parent.Id, Qref: $data.QuestionRefSetStrings , Uid: $data.Uid}">
                                                <!-- /ko -->
                                            </div>
                                            <!-- /ko -->
                                        </div>
                                        <div class="subQuestion" style="margin-left: 10px; margin-top: 10px" ></div>

                                    </div>
                                </div>

                            </div>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

用于自定义绑定的Knockout代码

var GuidelineQuestion =
    {

GetGuildlineQuestion: function () {

            var self = this;
            var ajaxUrl = ApplicationRootUrl("GetGuildlineQuestionold", "MCGGuidelines");
            $('#loading').show();

            $.ajax({
                type: "POST",
                url: ajaxUrl,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                cache: false,
                async: false,
                success: function (data) {
                    $('#MCGSectionHeader').text("Assessment");
                    self.customeGuideline(data.CustomGuideline);
                    self.GuidelinesQuestionHeading(data.Title);
                    self.GuidelinesQuestionList(data.SectionsSet);
                    self.GuidelinesSubmitList(data);
                    if (self.GuidelinesQuestionHeading() != null && self.GuidelinesQuestionHeading() != "") {
                        self.Split_GuidelinesQuestion_Array(self.GuidelinesQuestionHeading().split("-"));
                        self.SplitGuidelinesQuestionHeading(self.Split_GuidelinesQuestion_Array()[0]);
                    }

                    $('#loading').hide();
                    self.AnswerSaveButton(true);
                    original_questions = JSON.stringify(ko.toJS(self.GuidelinesSubmitList()));
                },
                error: function (err) {
                    $('#loading').hide();
                }
            });
        }







 $(document).ready(function () {

    ko.applyBindings(GuidelineQuestion, document.getElementById("GuidelineQuestionAnswers"));
        GuidelineQuestion.GetGuildlineQuestion();
             ko.bindingHandlers.trueFalseRadioButton =
            {
                init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                    // event handler for the element change event
                    console.log("hello" + valueAccessor());
                    var changeHandler = function () {
                        var elementValue = $(element).val();
                        var observable = valueAccessor();      // set the observable value to the boolean value of the element value
                        observable($.parseJSON(elementValue));
                    };    // register change handler for element
                    ko.utils.registerEventHandler(element,
                                                  "change",
                                                  changeHandler);
                },
                update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                    var elementValue = $.parseJSON($(element).val());
                    var observableValue = ko.utils.unwrapObservable(valueAccessor()); if (elementValue === observableValue) {
                        element.checked = true;
                    }
                    else {
                        element.checked = false;
                    }
                }
            };
        });
}

获得可观察的错误不是一个功能

javascript jquery knockout.js knockout-2.0
1个回答
0
投票

请听取意见中的建议。你是在和Knockout一起工作,而不是用它。阅读文档,阅读教程,并尝试使用checked绑定重写代码。

话虽如此,如果您转到当前路径,请确保在绑定处理程序中解包输入,以便您可以传递observable和plain属性。像这样:

var observable = ko.utils.unwrapObservable(valueAccessor);

对于你的例子:

ko.bindingHandlers.trueFalseRadioButton =
{
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // event handler for the element change event
        console.log("hello" + valueAccessor());
        var changeHandler = function () {
            var elementValue = $(element).val();
            var observable = ko.utils.unwrapObservable(valueAccessor);
            observable($.parseJSON(elementValue));
        };    // register change handler for element
        ko.utils.registerEventHandler(element,
                                      "change",
                                      changeHandler);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var elementValue = $.parseJSON($(element).val());
        var observableValue = ko.utils.unwrapObservable(valueAccessor()); if (elementValue === observableValue) {
            element.checked = true;
        }
        else {
            element.checked = false;
        }
    }
};

ko.applyBindings({
  Id: 1,
  items: [{
    Id: 2, 
    Selected: true,
    RadioOnly: ko.observable(true),
    QuestionRefSetStrings: "something",
    Uid: "uid"
  },{
    Id: 3, 
    Selected: true,
    RadioOnly: ko.observable(true),
    QuestionRefSetStrings: "something",
    Uid: "uid"
  }],
  answerClick: function(x){console.log(x);},
  appendQrefQuestion: function(x){console.log(x); return true;}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div data-bind="foreach: items">
  <input type="radio" data-bind="
    value: $data.RadioOnly, 
    attr:{
        id: $data.Id ,
        name:$parent.Id,
        Qid: $parent.Id,
        Qref: $data.QuestionRefSetStrings,
        Uid: $data.Uid
    },  
    trueFalseRadioButton: $data.Selected,
    click: $root.answerClick,
    if: $root.appendQrefQuestion($data.QuestionRefSetStrings)
  ">
</div>

然而,再一次,即使IMO回答了您的问题,使用您当前的设置,您将遇到大量的后续问题。尝试切换到使用checked绑定(可能使用可写的computed),或者不使用Knockout并全部使用jQuery。

© www.soinside.com 2019 - 2024. All rights reserved.