jsfiddle with knockout - 无法处理绑定“foreach:function()”

时间:2017-01-05 17:39:41

标签: knockout.js

我正在尝试将我的代码复制到一个小提琴中,在这里问一个问题,我甚至无法使小提琴工作!相同的代码在我的本地环境中工作正常。 Knockout抱怨无法处理foreach函数的绑定。具体来说:

  

jQuery.Deferred exception:无法处理绑定“foreach:   function(){return items}“消息:无法处理绑定”值:   function(){return itemNo}“消息:itemNo未定义为匿名/

这是我的代码段:

var viewModel;

var profitCode = function(code, desc, name) {
  this.code = code;
  this.desc = desc;
  this.name = name;
};

var codeModel = function(codes, items) {
  var self = this;
  self.codes = ko.observableArray([codes]);
  self.items = ko.observableArray([items]);
};

$(document).ready(function () {
  var codesJSON = '[{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1000","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1100","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1120","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1150","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1151","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"120","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"125","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1500","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"1600","profitCode":0,"profitCodeName":null,"wholesale":0},{"ExtensionData":null,"brochureId":0,"commission":0,"itemNo":"170","profitCode":0,"profitCodeName":null,"wholesale":0}]';
  var itemsJSON = '[{"ExtensionData":{},"brocCode":"1000","brochureId":1,"itemDesc":"Bicycle","itemNo":"1000","itemOrder":1,"prizeNum":0,"retail":13.5},{"ExtensionData":{},"brocCode":"1100","brochureId":1,"itemDesc":"Front Wheel","itemNo":"1100","itemOrder":2,"prizeNum":0,"retail":35},{"ExtensionData":{},"brocCode":"1120","brochureId":1,"itemDesc":"Spokes","itemNo":"1120","itemOrder":3,"prizeNum":0,"retail":12.5},{"ExtensionData":{},"brocCode":"1150","brochureId":1,"itemDesc":"Front Hub","itemNo":"1150","itemOrder":4,"prizeNum":0,"retail":5},{"ExtensionData":{},"brocCode":"1151","brochureId":1,"itemDesc":"Axle Front Wheel","itemNo":"1151","itemOrder":5,"prizeNum":0,"retail":14},{"ExtensionData":{},"brocCode":"120","brochureId":1,"itemDesc":"Loudspeaker, Black, 120W","itemNo":"120","itemOrder":6,"prizeNum":0,"retail":12.5},{"ExtensionData":{},"brocCode":"125","brochureId":1,"itemDesc":"Socket Back","itemNo":"125","itemOrder":7,"prizeNum":0,"retail":10},{"ExtensionData":{},"brocCode":"1500","brochureId":1,"itemDesc":"Lamp","itemNo":"1500","itemOrder":8,"prizeNum":0,"retail":6},{"ExtensionData":{},"brocCode":"1600","brochureId":1,"itemDesc":"Bell","itemNo":"1600","itemOrder":9,"prizeNum":0,"retail":8},{"ExtensionData":{},"brocCode":"170","brochureId":1,"itemDesc":"Brake","itemNo":"170","itemOrder":10,"prizeNum":20,"retail":5.5}]';

	var profitCodes = '[{"ExtensionData":{},"profitCode":1,"profitDesc":"A - STANDARD 40% PROFIT","profitName":"40A"},{"ExtensionData":{},"profitCode":2,"profitDesc":"B - STANDARD 40% PROFIT","profitName":"40B"}]';
            
	viewModel = new codeModel(codesJSON, itemsJSON);

  //console.log(viewModel);
  ko.applyBindings(viewModel, $("#profitModal")[0]);
                    
            /*
            $.ajax({
                url: '@Url.Action("GetProfitCodesJSON", "Brochure")',
                type: 'POST',
                data: { editing: false, brochureID: $.trim($("#brochureId").val()) },
                success: function(json) {
                    var codesJSON = @Html.Raw(Json.Encode(Model.brochureProfitCodes));
                    console.log(JSON.stringify(codesJSON));
                    var itemsJSON = @Html.Raw(Json.Encode(Model.brochureItems));
                    console.log(JSON.stringify(itemsJSON));
                    viewModel = new codeModel(codesJSON, itemsJSON);
                    $.each(json.profitCodes, function(index, value) {
                        var code = new profitCode(value.profitCode, value.profitDesc, value.profitName);
                        viewModel.availableProfitCodes.push(code);
                    });
                    console.log(viewModel);
                    ko.applyBindings(viewModel, $("#profitModal")[0]);
                }
            });
						*/
        });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4>Add Profit Code</h4>

<div class="modal-body" id="profitModal">
<form action="/Brochure/SaveProfitCodes" id="myForm" method="post">
        <hr />
        <div class="row">
            <table class="table table-bordered table-striped" id="profitCodes">
                <thead>
                    <tr>
                        <th>
                            Item No
                        </th>
                        <th>
                            Bro Code
                        </th>
                        <th width="38%">
                            Item Desc
                        </th>
                        <th width="14%">
                            Retail
                        </th>
                        <th>
                            Wholesale
                        </th>
                        <th>
                            Commission
                        </th>
                    </tr>
                </thead>
                <tbody data-bind="foreach: items">
                    <tr>
                        <td>
                            <input data-bind="value: itemNo, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" />
                        </td>
                        <td>
                            <input data-bind="value: brocCode, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" />
                        </td>
                        <td>
                            <input data-bind="value: itemDesc, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" />
                        </td>
                        <td>
                            <input data-bind="value: retail, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" />
                        </td>
                        <td>
                            <input data-bind="value: wholesale, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" />
                        </td>
                        <td>
                            <input data-bind="value: commission, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" />
                        </td>
                    </tr>
            </table>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button type="button" id="profitCodeSave" class="btn btn-primary">Save Changes</button>
        </div>
</form>
</div>

我的小提琴:https://jsfiddle.net/j9hskr51/3/

1 个答案:

答案 0 :(得分:1)

您将字符串视为JSON对象。首先,你必须解析它:

viewModel = new codeModel(JSON.parse(codesJSON), JSON.parse(itemsJSON));

然后,要小心你将什么传递给observable数组,因为解析的JSON已经是一个数组。因此:

self.codes = ko.observableArray(codes);
self.items = ko.observableArray(items);