如何在Knockout.js中将项添加到JSON中

时间:2016-09-19 14:27:17

标签: knockout.js

编辑:我希望能够在对象中添加任何元素,而不仅仅是特定年龄。

有没有办法在Knockout.js中将项添加到JSON中? 我想在下面的现有JSON中添加age并将其反映在网页上。我的代码中的click函数将年龄添加到JSON上,但无法在页面上显示。 我还尝试使用cleanNode()+ applybindings重新应用绑定,但foreach中的项目是重复的

html:

<div data-bind="text: $data.name, visible: $data.name !== undefined" ></div>
<div data-bind="text: $data.age, visible: $data.age !== undefined" ></div>
<div data-bind="foreach: children">
  <div data-bind="text: $data.name"></div>
</div>
<button id="button">Test</button>

代码:

json = {
    name: 'Scott',
    children: [
        { id : 1, name : 'Alice' },
        { id : 2, name : 'Liv' }
    ]
}

var viewModel = ko.mapping.fromJS( json );
ko.applyBindings( viewModel, document.body );

document.getElementById( "button" ).addEventListener( "click", function() {
    json.age = "87";
    ko.mapping.fromJS( json, viewModel );
} );

小提琴示例: https://jsfiddle.net/f8qbu1j8/6/

3 个答案:

答案 0 :(得分:0)

在原始JSON对象上设置age属性,即使将其留空也是如此。这将使其正确映射到您的视图模型。然后,稍后,您可以在视图模型上设置年龄值,而无需重新映射。您应该只需要在对象上使用ko.mapping一次。见下文:

HTML:

my_file = h5py.File(h5filename, 'r')
file_image = my_file['/imagePatches']
li = dataframe["label"]
temporary_list = file_image

# select images whose indices exist in "in"
labeled_dataset = list(temporary_list[in])

# select images whose indices don't exist in "in"
unlabeled_dataset = np.delete(temporary_list, in, 0)

JavaScript的:

<div data-bind="text: $data.name, visible: $data.name !== undefined"></div>
<div data-bind="text: $data.age, visible: $data.age !== undefined"></div>
<div data-bind="foreach: children">
  <div data-bind="text: $data.name"></div>
</div>
<button id="button">Test</button>

工作小提琴:https://jsfiddle.net/dw1284/nvckyta4/

答案 1 :(得分:0)

我赞成丹尼斯的回答。绑定你的&#34; viewModel&#34;对于元素&#34; document.body&#34;,你可以通过设置&#34; viewModel&#34;的值来改变你的json。 :

<div data-bind="text: $data.name, visible: $data.name !== undefined"></div>
<div data-bind="text: $data.age, visible: $data.age !== undefined"></div>
<div data-bind="foreach: children">
  <div data-bind="text: $data.name"></div>
</div>
<button id="button">Test</button>

javascript部分:

var json = {
    name: 'Scott',
    children: [
        { id : 1, name : 'Alice' },
        { id : 2, name : 'Liv' }
    ],
    age: null
}

var viewModel = ko.mapping.fromJS({});
ko.mapping.fromJS(json, viewModel);
ko.applyBindings(viewModel, document.body);

document.getElementById("button").addEventListener("click", function() {
  viewModel.age(87); // edit the property "age"
  viewModel.children.push({id : 3, name : 'Adil' }); // add element to the property "children"
});

答案 2 :(得分:0)

第一次使用mapping plugin时,它会根据您的对象为您创建一个视图模型。由于您的对象没有age属性,因此您在模型中没有年龄的可观察变量。使用新对象更新现有视图模型后,它只会更新之前已创建并存在于模型中的变量。

除此之外,由于您使用的是knockout,因此您应该使用淘汰的功能,并避免在模型中使用jquery,我可以在您使用Jquery的代码中看到click事件。正如您可能会阅读knockout.js文档一样,knockout使用click绑定为您完成此任务。

我假设您将拥有一系列对象,这是我的建议如何实现您的模型,以便将来更容易维护您的模型,因为您可能希望为其添加新的功能。

示例:https://jsfiddle.net/9aLvd3uw/248/

HTML:

 <div data-bind="foreach :Items">
    <div data-bind="text: name, visible:name " ></div>
    <div data-bind="text: age, visible: age" ></div>
    <div data-bind="foreach: children">
        <div data-bind="text: name" class="nested"></div>
    </div>
    <button data-bind="click:$parent.UpdateAge">Update age to 87</button>
  </div>

JS:

var json = [{
    name: 'Scott',
    children: [
        { id : 1, name : 'Alice' },
        { id : 2, name : 'Liv' }
    ],
    age:null
},{
    name: 'Kevin',
    children: [
        { id : 3, name : 'Mike' },
        { id : 4, name : 'Alex' }
    ],
    age:55
}];
var MainViewModel = function (){
    var self = this;
  self.Items = ko.observableArray();
  self.Items($.map(json, function (item) {
    return new ItemViewModel(item);
  }));
    self.UpdateAge = function(item){
    //here you can have your logic to update the age.
    item.age(87);
  }
}
  var ItemViewModel = function (data){
    var self = this;
    self.name = ko.observable(data.name);
    self.children = ko.observableArray(data.children);
    self.age = ko.observable(data.age);
  }
 var vm = new MainViewModel();
ko.applyBindings(vm);