javascript - knockout.js get parent observable - Stack Overflow
Is it possible to get parent observable in knockout? Like I have
<div data-bind="parent: {...}">
<div data-bind="child: {...}">
...
</div>
</div>
I want to get access to parent in child but not in the markup but in the code. How can I achieve in a standard knockout way?
UPDATE I have found a simple way to achieve this by simply accessing the last argument of custom handler like this:
ko.bindingHandlers.custom = {
init: function (element, valueAccessor, allBindingsAccessor, vm, bindingContext) {
console.log(bindingContext.$parent);
}
}
Is it possible to get parent observable in knockout? Like I have
<div data-bind="parent: {...}">
<div data-bind="child: {...}">
...
</div>
</div>
I want to get access to parent in child but not in the markup but in the code. How can I achieve in a standard knockout way?
UPDATE I have found a simple way to achieve this by simply accessing the last argument of custom handler like this:
ko.bindingHandlers.custom = {
init: function (element, valueAccessor, allBindingsAccessor, vm, bindingContext) {
console.log(bindingContext.$parent);
}
}
Share
Improve this question
edited Mar 12, 2014 at 11:02
lukas.pukenis
asked Mar 12, 2014 at 10:14
lukas.pukenislukas.pukenis
13.6k13 gold badges49 silver badges83 bronze badges
0
2 Answers
Reset to default 3You can use $parent
to access the parent item:
<div data-bind="parent: {...}">
<div data-bind="child: {...}">
<span data-bind="text: $parent.someObservable()"></span>
<span data-bind="text: somefunction($parent.someObservable())"></span>
</div>
</div>
The most simple way it to past parent object to child model as a parameter (pointer) when child object constructed. But it more standard javascript way then knockout
var Parent = function (item) {
var self = this;
this.value = ko.observable(item.value);
this.child = new Child(item.child, self);
}
var Child = function (item, parent) {
var self = this;
this.parent = parent;
this.value = ko.observable(item.value);
}
and HTML markup will look like
This is <b><span data-bind="text: value"></span></b>
<div data-bind="with: child">
This is <b><span data-bind="text: value"></span></b>
<br/>
This is <b><span data-bind="text: parent.value"></span></b> of <b><span data-bind="text: value"></span></b>
</div>
JSFIDDLE
To prevent big amount of code mapping plugin could be used and it will be more knockout way
var Parent = function (item) {
var self = this;
var map = {
'child': {
update: function(options) {
return new Child(options.data, self);
}
}
}
ko.mapping.fromJS(item, map, self);
}
var Child = function (item, parent) {
var self = this;
this.parent = parent;
ko.mapping.fromJS(item, null, self);
}
JSFIDDLE
And the most knockout way - it to create custom binding that will controls descendant bindings. In this way you can extend child context with extra properties.
ko.bindingHandlers.withParent = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Make a modified binding context, with a extra properties, and apply it to descendant elements
ko.mapping.fromJS({
parent: bindingContext.$rawData
}, null,valueAccessor());
var childBindingContext = bindingContext.createChildContext(valueAccessor, null, null);
ko.applyBindingsToDescendants(childBindingContext, element);
// Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
return { controlsDescendantBindings: true };
}
};
Model
var Parent = function (item) {
var self = this;
var map = {
'child': {
update: function(options) {
return new Child(options.data);
}
}
}
ko.mapping.fromJS(item, map, self);
}
var Child = function (item, parent) {
var self = this;
ko.mapping.fromJS(item, null, self);
}
and HTML
This is <b><span data-bind="text: value"></span></b>
<div data-bind="withParent: child">
This is <b><span data-bind="text: value"></span></b>
<br/>
This is <b><span data-bind="text: parent.value"></span></b> of <b><span data-bind="text: value"></span></b>
<br/>
<input type="button" value="Test from code" data-bind="click: test"/>
</div>
JSFIDDLE
But personaly me not like this approach, because using together with 'with', 'foreach' or 'tempalate' bindings it could cause errors like
Message: You cannot apply bindings multiple times to the same element.
- Win11革命性新变化来了!31年的NTFS被取代:ReFS将成默认文件系统
- SaaS 的历史与变革
- 苹果WWDC2014:iOS 8新功能都有哪些?
- 台式电脑“玩”安卓(图)
- c++ - Why is my OpenGL application rendering a 3D model with unexpected transparency? - Stack Overflow
- audio - How can i improve my sound module in Java? - Stack Overflow
- php - Laravel RouteServiceProvider missing in appProviders directory - Stack Overflow
- python - Why does my plot have criss-crossing lines when I convert the index from string to datetime? - Stack Overflow
- javascript - How to create perfect hash with ASCII symbols as input, where output hash is always the same for each ASCII sequenc
- python - NaN values in Pandas are not being filled by the interpolate function when it's applied to a full dataframe - S
- javascript - Responsiveness textContent (graphic) - Stack Overflow
- python - invoke matplotlib toolbar keeping custom views history - Stack Overflow
- How to create a custom TimeFormatStyle for just seconds for a Swift Duration - Stack Overflow
- reflection - java.lang.reflect.field.set(obj,value) fails for applicationscoped - Stack Overflow
- React Native Build Error on Windows: "EMFILE: too many open files" During `assembleRelease` - Stack Overflow
- outlook - Unable to send email using Microsoft Graph API: Error 550 5.7.708 - Stack Overflow
- tsconfig - Is there a typescript compiler option that prevents implicit widening from readonly properties to readwrite? - Stack