KnockoutJS映射没有

时间:2013-11-04 22:51:39

标签: knockout.js knockout-mapping-plugin

我有一个包含诊断代码数组的viewmodel。在我的html中,我有一个按钮数据绑定到一个单击,向数组添加一个空白的诊断代码。这一切都有效。

我使用按钮添加诊断代码。这很有效。

我从外部源接收JSON,然后尝试将其包装在一个observable中。因为它来自外部源,所以它没有我可以绑定的函数,所以我绑定到不属于viewModel的函数。

当我尝试将对象转换回JSON字符串时,新的诊断代码是空字符串(我在新代码时添加的默认值)。

以下是代码:

 <h3>Diagnosis Codes<input type="button" value="Add" data-bind="click:AddDiagnosisCode"/></h3>
    <div data-bind="foreach:DiagnosisCodes">
        <div><input type="text"  data-bind="value:$data"/><input type="button" value="Remove" data-bind="click: function(data, event) { RemoveDiagnosisCode($parent, data, event) }"/>
        </div>
    </div>

    <script type="text/javascript">
        function AddDiagnosisCode(item)
        {
            item.DiagnosisCodes.push("");
        }

        function RemoveDiagnosisCode(item, code) {
            item.DiagnosisCodes.remove(code);
        }

        function submitJSON() {
            var test= ko.mapping.toJSON(viewModel); // have also tried ko.toJSON(viewModel)
            alert(test);
        }

        var vm = {
           "DiagnosisCodes": ["2345","6789"]
        };

        var viewModel = ko.mapping.fromJS(vm);     
         ko.applyBindings(viewModel);
    </script>

例如,如果我单击Add并键入代码ABCD然后调用submitJSON,我看到:

{
    DiagnosisCodes:["2345","6789",""]
}

我期待

{
    DiagnosisCodes:["2345","6789","ABCD"]
}

UPDATE:看起来映射插件将简单类型(字符串,整数等)的数组转换为observable而不是observableArrays。所以我在调用映射之前修改了(用pax的帮助)javascript来将字符串数组转换为包含字符串的对象数组。然后在转换为JSON时,将它们转换回来:

<h3>Diagnosis Codes<input type="button" value="Add" data-bind="click:AddDiagnosisCode"/></h3>
    <div data-bind="foreach:DiagnosisCodes">
        <div><input type="text"  data-bind="value:code"/><input type="button" value="Remove" data-bind="click: $root.RemoveDiagnosisCode"/>
        </div>
    </div>
<button onclick="submitJSON()">Show</button>

function submitJSON() {
            //convert to JS object first
            var test= ko.mapping.toJS(viewModel);
            UnMapCodes(test);

            alert(ko.toJSON(test));
        }

           function Code(code)
        {
            var self=this;
            self.code = code;
        }

        function MapToCodes(obj)
        {
            var codes=[];

            for(var c=0; c<obj.DiagnosisCodes.length; c++)
            {
                codes.push(new Code(obj.DiagnosisCodes[c]));
            }

            obj.DiagnosisCodes=codes;
        }

        function UnMapCodes(obj)
        {
            var codes=[];

            for(var c=0; c<obj.DiagnosisCodes.length; c++)
            {
                codes.push(obj.DiagnosisCodes[c].code);
            }

            obj.DiagnosisCodes=codes;
        }


        var vm = {            
           "DiagnosisCodes": ["2345","6789"]
        };

        vm.AddDiagnosisCode= function (item)
            {
                self=this;
                self.DiagnosisCodes.push(new Code(""));
            };
        vm.RemoveDiagnosisCode= function (code) {
                self=this;
                self.DiagnosisCodes.remove(code);
            };

        MapToCodes(vm);

        var viewModel = ko.mapping.fromJS(vm);     
         ko.applyBindings(viewModel);

1 个答案:

答案 0 :(得分:2)

代码有几个问题,重新构建了一点(小提琴:http://jsfiddle.net/VX9f2/2/):

HTML:

<button data-bind="click:submitJSON">submit json</button>
<h3>Diagnosis Codes<input type="button" value="Add" data-bind="click:AddDiagnosisCode"/></h3>
    <div data-bind="foreach:DiagnosisCodes">
        <div><input type="text"  data-bind="value:code"/><input type="button" value="Remove" data-bind="click: $root.RemoveDiagnosisCode"/>
        </div>
    </div>

JS:

var Code = function(code){
    var self = this;
    self.code = ko.observable(code);
}

var VM = function(){
    var self = this;
    self.DiagnosisCodes = ko.observableArray([
        new Code("2345"),
        new Code("6789")]);
    self.AddDiagnosisCode = function() {
        self.DiagnosisCodes.push(new Code(""));
    }

    self.RemoveDiagnosisCode = function(item) {
         self.DiagnosisCodes.remove(item);
    }

    self.submitJSON = function() {
        var test= ko.mapping.toJSON(self.DiagnosisCodes); // have also tried ko.toJSON(viewModel)
        alert(test);
        }

}
       //var viewModel = ko.mapping.fromJS(new VM());     
         ko.applyBindings(new VM());

为清楚起见,我用构造函数替换了初始ko.mapping用法。它仍然希望使用它,请告诉我。