Reputation: 199
I have here some sample code for knockoutjs components in which I have a problem in need of solving:
<template id="item-list-tmpl">
<ul data-bind="foreach: MyList">
<li>
<span data-bind="text: $data.DisplayText"></span>
<span data-bind="text: $root.DeleteItem"></span>
</li>
</ul>
</template>
ko.components.register('item-list', {
template: $("#item-list-tmpl").html(),
viewModel: function (params) {
self.MyList = params.MyList; // object inside this list { DisplayText: "Sample Text" }
}
});
I want to know how I can access the Delete
function on my root view model
Here's how I'm using the component:
<div data-bind='component:{
name: "item-list"
params: {
MyList: myVM.MyList
}
}'></div>
Here is my main view model code structure where MyList
resides:
function MainVM(){
var self = this;
self.MyList = ko.observableArray([{ DisplayText: "Sample Text" }]);
self.Delete = function(value){
self.MyList.remove(value);
};
}
My problem here is that I can't seem to access the Delete
function from my main view model inside the list elements. Does anyone here have an idea of what was happening?
Upvotes: 1
Views: 548
Reputation: 63709
But you don't want to access Delete
on the root object, because I don't think it's there. Instead, it seems it'll be on the root's myVM
property.
Because you do MyList: myVM.MyList
you effectively skip one layer of context, so myVM
is never really the context, and you'll always have to refer to it again when you access the root. So something like $root.myVM.Delete
should work. Alternatively you can get there through the $parents[]
hierarchy:
ko.components.register('item-list', {
template: $("#item-list-tmpl").html(),
viewModel: function (params) {
self.MyList = params.MyList; // object inside this list { DisplayText: "Sample Text" }
}
});
function MainVM(){
var self = this;
self.MyList = ko.observableArray([{ DisplayText: "Sample Text" }]);
self.Delete = function(value){ console.log(value);
self.MyList.remove(value);
};
}
ko.applyBindings({myVM: new MainVM()});
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<template id="item-list-tmpl">
<ul data-bind="foreach: MyList">
<li>
<span data-bind="text: $data.DisplayText"></span>
<button data-bind="click: $root.myVM.Delete">$root.myVM.Delete</button>
<button data-bind="click: $parents[1].myVM.Delete">$parents[1].myVM.Delete</button>
</li>
</ul>
</template>
<div data-bind='component: {
name: "item-list",
params: { MyList: myVM.MyList }
}'></div>
<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
Upvotes: 1