Knockout:将项添加到嵌套的json层次结构中

时间:2016-06-23 14:16:21

标签: knockout.js

我想知道如何在嵌套层次结构中添加项目。当我没有使用映射插件时,我能够做到这一点,但仅限于顶层。

这里是小提琴:https://jsfiddle.net/kyr6w2x3/3/

<input type="text" 
data-bind="value: newSlideTitle" placeholder="Awesome slide name"> 

<button type="button" 
data-bind="click: $root.addSlide.bind($parent, $data)">Add slide</button> 


self.removeSlide = function(slide) { this.slides.remove(slide)  };
self.addSlide = function(slide) {
    this.slides.push(new Slide({ 
        slideTitle: this.newSlideTitle(), 
        slideImage: this.newSlideImage()
        }));
    self.newSlideTitle("");
    self.newSlideImage("");
};

我想知道如何使表单(html的第20行)工作,因此它添加了幻灯片。谢谢!

1 个答案:

答案 0 :(得分:1)

我会做什么,我会为每个数组创建一个单独的视图模型,并尝试以某种方式保留它们,以便您可以轻松地添加该VM的新实例,并且您也可以访问每个observableArray以添加或进行任何操作。


在您的代码中,您无权访问this.slides来推送new Slide,而我无法在您的代码中找到它。
示例:https://jsfiddle.net/kyr6w2x3/6/

    function PageItemViewModel(data){
      var self = this;
      self.pageName = ko.observable(data.pageName);
      self.pageRows = ko.observableArray([]);
      // create a new instance of PageRowItemViewModel for each data.pageRows
      self.pageRows($.map(data.pageRows, function (item) {
         return new PageRowItemViewModel(item);
      })); 
    }
    function PageRowItemViewModel(data){
      var self = this;
      self.rowType = ko.observable(data.rowType);
      self.slides = ko.observableArray([]);
      self.rowBackgroundColor = ko.observable(data.rowBackgroundColor);
      // create a new instance of SlideItemViewModel for each data.slides
      self.slides($.map(data.slides, function (item) {
           return new SlideItemViewModel(item);
      }));
    }
    function SlideItemViewModel(data){
      var self = this;
      self.slideTitle = ko.observable(data.slideTitle);
      self.slideImage = ko.observable(data.slideImage);
    }
    function ViewModel(data){
    var self = this;
    // Define an observableArray
    self.pages = ko.observableArray([]);
    self.OutputJson = function(){
        console.log(ko.toJSON(self));
    }
     self.newSlideTitle = ko.observable();
     self.newSlideImage = ko.observable();
     // create a new instance of PageItemViewModel for each website 
    self.pages($.map(website, function (item) {
      return new PageItemViewModel(item);
    }));

    self.removePage = function(pageName) { self.pages.remove(pageName) };
    self.removeRow = function(rowType) { this.pageRows.remove(rowType) };
    self.addRow = function(rowType) {
    //
    }
        self.removeSlide = function(slide) { this.slides.remove(slide)  };
    self.removeSlide = function(slide) { this.slides.remove(slide)  };

    self.addSlide = function(item) {
        //here you have an access to your item which is an instance of your PageRowItemViewModel 
         item.slides.push( new SlideItemViewModel({slideTitle :self.newSlideTitle() ?self.newSlideTitle() : "NEW" ,slideImage :self.newSlideImage() ? self.newSlideImage() : "NEW IMAGE" }));
    };

}
// rowImages:" 'image1.jpg','image2.jpg','image3.jpg' "
var website = [ 
    {pageName: "Home", pageType:"home", pageRows: [
        {rowType: "slideshow", rowBackgroundColor: "#ddddef", slides: [    
            { slideTitle:"Fabulous", slideImage:"img1.png"},
            { slideTitle:"Amazing", slideImage:"img2.png"},
            { slideTitle:"Elegant", slideImage:"img3.png"}
        ] },
        {rowType: "slideshow", rowBackgroundColor: "#ffddcc", slides: [    
            { slideTitle:"Wonderful", slideImage:"img1.png"},
            { slideTitle:"Compelling", slideImage:"img2.png"},
            { slideTitle:"Magestic", slideImage:"img3.png"}
        ] }
    ]
    },
    {pageName: "about", pageRows: []},
    {pageName: "contact", pageRows: []}
];


_vm  = new ViewModel(website);
ko.applyBindings(_vm );