
Question:
I would like to know how to add items within a nested hierarchy. I was able to do it when I was not using the mapping plugin, but only in the top level.
Here's the Fiddle: <a href="https://jsfiddle.net/kyr6w2x3/3/" rel="nofollow">https://jsfiddle.net/kyr6w2x3/3/</a>
<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("");
};
I would like to know how to make the form (line 20 of html) working so it adds a slide. Thanks!
Answer1:What I would do, I'd create a separate View Model for each Array and try to keep them in a way so you would be able to add a new instance of that VM
easily and also you are able to access to each observableArray
in order to add or any manipulations.
<br />
In your code you don't have an access to this.slides
to push new Slide
which I could not find it in your code. <br />
Example : <a href="https://jsfiddle.net/kyr6w2x3/6/" rel="nofollow">https://jsfiddle.net/kyr6w2x3/6/</a>
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 );