试图多次更新Knockout Js Viewmodel

时间:2013-01-27 02:29:39

标签: javascript mvvm knockout.js

我是Knockout JS领域的新手。我试图在绑定新的JSON对象后更新我的视图模型。但是,我的尝试是徒劳的。谁能看到我做错了什么? (下面是我的样本小提琴)。

JS

var strRawJSON = "{\"CPTResults\":[{\"CPT\":{\"RecordKey\":\"b8a335ab-0dda-448d-bb64-943a3cb1b586\",\"Code\":\"82947\",\"Description\":\"Glucose quantitative blood (except reagent strip)\"},\"ErrorA\":\"\",\"ErrorB\":\"\",\"ErrorC\":\"\",\"ErrorD\":\"\",\"ErrorE\":\"\",\"ErrorF\":\"\",\"MedPolicyDesc\":\"Blood Glucose Testing\",\"MedPolicyRef\":\"190.20\",\"MedPolicyWebLink\":\"http:\/\/www.cms.gov\/medicare-coverage-database\/details\/ncd-details.aspx?NCDId=98&ncdver=2&bc=AAAAgAAAAAAA&\",\"Questions\":[{\"Question\":\"If Pre-Diabetic, does the test frequency exceed one screening per 6 months?\",\"QuestionExplanation\":\"For Individuals diagnosed with Pre-Diabetes, only 2 screening test smay be performed per year, at six-month intervals. Providers should note that these testsd with a pre-diabeted diagnosis must be billed with a V77.1 diagnosis code, and a \\\"TS\\\" modifier to reflect follow up service.\\n\\nPre-Diabetes: abnormal glocose metabolism daignosed froma previous fasting glucose level of 100 to 125 mg\/dl, or a 2-hour post-glucose challenge of 140 to 199 mg\/dl. The term \\\"pre-daibetes\\\" \\nincludes impaired fasting glucose and impaired glucose tolerance.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":{\"OptionText\":\"No\",\"OptionValue\":\"pass\"},\"isFrequency\":true,\"ABNStatement\":\"\"},{\"Question\":\"For Routine Diabetic screening, does the test frequency exceed 1 per year?\",\"QuestionExplanation\":\"Effective for services on or after January 1, 2005, Medicare will pay for diabetic screening tests under the Medicare Clinical Laboratory Fee Schedule.\\n\\nTo indicate that the purpose of the test(s) is for diabetic screening, a screening diagnosis code (V77.1) is required in the diagnosis section of the claim.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":{\"OptionText\":\"No\",\"OptionValue\":\"pass\"},\"isFrequency\":true,\"ABNStatement\":\"\"}]}]}";
var strRawJSON2 = "{\"CPTResults\":[{\"CPT\":{\"RecordKey\":\"b8a335ab-0dda-448d-bb64-943a3cb1b586\",\"Code\":\"82947\",\"Description\":\"Test quantitative blood (except reagent strip)\"},\"ErrorA\":\"\",\"ErrorB\":\"\",\"ErrorC\":\"\",\"ErrorD\":\"\",\"ErrorE\":\"\",\"ErrorF\":\"\",\"MedPolicyDesc\":\"Blood Glucose Testing\",\"MedPolicyRef\":\"190.20\",\"MedPolicyWebLink\":\"http:\/\/www.cms.gov\/medicare-coverage-database\/details\/ncd-details.aspx?NCDId=98&ncdver=2&bc=AAAAgAAAAAAA&\",\"Questions\":[{\"Question\":\"If Pre-Diabetic, does the test frequency exceed one screening per 6 months?\",\"QuestionExplanation\":\"For Individuals diagnosed with Pre-Diabetes, only 2 screening test smay be performed per year, at six-month intervals. Providers should note that these testsd with a pre-diabeted diagnosis must be billed with a V77.1 diagnosis code, and a \\\"TS\\\" modifier to reflect follow up service.\\n\\nPre-Diabetes: abnormal glocose metabolism daignosed froma previous fasting glucose level of 100 to 125 mg\/dl, or a 2-hour post-glucose challenge of 140 to 199 mg\/dl. The term \\\"pre-daibetes\\\" \\nincludes impaired fasting glucose and impaired glucose tolerance.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":{\"OptionText\":\"No\",\"OptionValue\":\"pass\"},\"isFrequency\":true,\"ABNStatement\":\"\"},{\"Question\":\"For Routine Diabetic screening, does the test frequency exceed 1 per year?\",\"QuestionExplanation\":\"Effective for services on or after January 1, 2005, Medicare will pay for diabetic screening tests under the Medicare Clinical Laboratory Fee Schedule.\\n\\nTo indicate that the purpose of the test(s) is for diabetic screening, a screening diagnosis code (V77.1) is required in the diagnosis section of the claim.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":{\"OptionText\":\"No\",\"OptionValue\":\"pass\"},\"isFrequency\":true,\"ABNStatement\":\"\"}]}]}";
var strModifiedJSON = "{\"CPTResults\":[{\"CPT\":{\"RecordKey\":\"b8a335ab-0dda-448d-bb64-943a3cb1b586\",\"Code\":\"82947\",\"Description\":\"Glucose quantitative blood (except reagent strip)\"},\"ErrorA\":\"\",\"ErrorB\":\"\",\"ErrorC\":\"\",\"ErrorD\":\"\",\"ErrorE\":\"Medicare may not pay for this test based on frequency limitations.\",\"ErrorF\":\"\",\"MedPolicyDesc\":\"Blood Glucose Testing\",\"MedPolicyRef\":\"190.20\",\"MedPolicyWebLink\":\"http:\/\/www.cms.gov\/medicare-coverage-database\/details\/ncd-details.aspx?NCDId=98&ncdver=2&bc=AAAAgAAAAAAA&\",\"Questions\":[{\"Question\":\"If Pre-Diabetic, does the test frequency exceed one screening per 6 months?\",\"QuestionExplanation\":\"For Individuals diagnosed with Pre-Diabetes, only 2 screening test smay be performed per year, at six-month intervals. Providers should note that these testsd with a pre-diabeted diagnosis must be billed with a V77.1 diagnosis code, and a \\\"TS\\\" modifier to reflect follow up service.\\n\\nPre-Diabetes: abnormal glocose metabolism daignosed froma previous fasting glucose level of 100 to 125 mg\/dl, or a 2-hour post-glucose challenge of 140 to 199 mg\/dl. The term \\\"pre-daibetes\\\" \\nincludes impaired fasting glucose and impaired glucose tolerance.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},\"isFrequency\":true,\"ABNStatement\":\"\"},{\"Question\":\"For Routine Diabetic screening, does the test frequency exceed 1 per year?\",\"QuestionExplanation\":\"Effective for services on or after January 1, 2005, Medicare will pay for diabetic screening tests under the Medicare Clinical Laboratory Fee Schedule.\\n\\nTo indicate that the purpose of the test(s) is for diabetic screening, a screening diagnosis code (V77.1) is required in the diagnosis section of the claim.\",\"QuestionPossibleAnswers\":[{\"OptionText\":\"Yes\",\"OptionValue\":\"fail\"},{\"OptionText\":\"No\",\"OptionValue\":\"pass\"}],\"QuestionUserAnswer\":null,\"isFrequency\":true,\"ABNStatement\":\"\"}]}]}";
var viewModel;

$('#MedNecContainer').removeClass('hide');
var objViewModel = ko.mapping.fromJSON(strRawJSON, CPTResultsMappingOptionsFunctions);

viewModel = { 
    list: objViewModel
};

console.log('objViewModel.CPTResults.length:' + objViewModel.CPTResults().length);
console.log('viewModel.list.length:' + viewModel.list.length);
console.log('viewModel.list.CPTResults.length:' + viewModel.list.CPTResults().length);

ko.applyBindings(viewModel, document.getElementById("MedNecContainer"));


setInterval(function() {
    var newList = ko.mapping.fromJS(strModifiedJSON);        
    viewModel.list = newList;
    console.log('reload');
},1000);


function CPTResultsMappingOptionsFunctions() {
    var self = this;
    var i = 0;
    self.setDropdownOnChange = function (elements, data) {
        $(".cpt-question").bind("change", function (event) {
        });

    }
}

HTML /模板:

<div class="widget hide" id="MedNecContainer">
    <div class="widget-header">
        <h3>Med Nec Results</h3>
    </div>
    <div class="widget-content">
        <div class="controls controls-row">
            <table class="table table-bordered table-hover" >
                <thead>
                    <tr>
                        <th>#</th>
                        <th>CPT© Code</th>
                        <th>Error E</th>
                        <!--th>Description</th-->
                        <th>Question(s)</th>
                        <th>Status</th>
                    </tr>
                </thead>
                <tbody id="tbCPTResults" data-bind="template: { name: 'med-nec-results-row', foreach:list.CPTResults(), 'if': list.CPTResults() && list.CPTResults().length > 0}">  

                </tbody>
            </table>                  
        </div>
    </div>
</div>

<script type="text/html" id="tweetsTemplate">
 </script>         


<script type="text/html" id="med-nec-results-row">
    <tr>
        <td data-bind="text: $index"></td>
        <!--td data-bind="text: cptAndDescription"></td-->
        <td data-bind="text: CPT.Description"></td>
        <td data-bind="text: ErrorE"></td>
        <td>
            <table class="table table-bordered">
                <tbody data-bind="template: {   name: 'med-nec-results-question-row', 
                                                foreach: Questions(), 
                                                'if': Questions() && Questions().length > 0
                                             }">    
                </tbody>
            </table>
        </td>
        <td></td>
    </tr>
</script>

<script type="text/html" id="med-nec-results-question-row">
    <tr class="med-nec-questions">
        <td data-bind="text:Question"></td>
        <!--td data-bind="text:QuestionExplanation"></td-->
        <td>
            <select class="cpt-question" data-bind="options: QuestionPossibleAnswers,  
                                                    optionsText: 'OptionText', 
                                                    value: QuestionUserAnswer, 
                                                    optionsCaption: 'Choose...'">
            </select>
        </td>
    </tr>
</script>

http://jsfiddle.net/dagr8anil/JBby7/89/

1 个答案:

答案 0 :(得分:1)

一些事情:

  1. 您需要对viewModel.list进行观察,以便您的观点能够对list分配给新值做出反应:

    viewModel = { 
        list: ko.observable(objViewModel)
    };
    
  2. 您还需要像使用初始数据调用映射函数一样调用映射函数。还要确保通过传递newList来更新observable:

    var newList = ko.mapping.fromJSON(strModifiedJSON, CPTResultsMappingOptionsFunctions);     
    viewModel.list(newList);
    
  3. 最后,您需要更新template上的tbody绑定:

    <tbody id="tbCPTResults" data-bind="template: { name: 'med-nec-results-row', foreach:list().CPTResults(), 'if': list().CPTResults() && list().CPTResults().length > 0 }">
    
  4. 更新示例: http://jsfiddle.net/JBby7/91/