问题
I've got a situation where I'd like to notify a grandparent or $parents[1] of a click event that occurs in a sub viewmodel. So basically I'd like to be able to do this
self.$parents[1].actionTaken
I think this doesn't work because of binding context vs viewModel but I'd like to hear if anyone has an ideas on the correct way to do something like this. Thanks
self.save = function () {
//do stuff to self first, then
self.$parents[1].actionTaken();
};
回答1:
Alternatively, you can pass parameters to your view model's event handler the following way:
Change your save method
self.save = function(theParents) {
theParents[1].actionTaken();
}
and bind your handler the following way:
data-bind="click: function() { $data.save($parents) }"
For further information, please refer to Note 2 in the click handler's documentation (you need to scoll down a bit)
回答2:
Or use the bind trick
data-bind="click: $parent.foo.bind($parent)"
Now when you access your foo function the this keyword will point to the parent context.
foo: function(child) {
this.children.remove(child);
}
回答3:
Nowadays (using knockout 3.0.0) one can just add two parameters to the child function (executed by the click binding), the first one will be assigned the current viewmodel and the second one will be assigned the click event args.
Then call ko.contextFor() and pass the event target and you will have access to $parent through the context object.
this.myChildFunction = function (vm, e) {
var context = ko.contextFor(e.target);
context.$parent.myParentFunction();
};
(don't know if this was possible during the time of the other answers...)
回答4:
Actually, actions are defined in viewmodel in knockoutjs' world. And the $parents/$data are 'context'. I create a data structure to demonstrate your need. Company > Sales department > Employees
You may find it in this jsfiddle example: invoke root action in child event
If you still want to do this in some reason, you may also define the actionTaken() function in grandparents' context(not as a viewmodel method). But that may be not a usual way. Whatever, check this out:
self.company={name:'ABC', click:function(){self.onCompClicked();}, salesDepartment:{manager:'Mgr',employees:['Smith','John']}};
Then change the binding click event to this:
data-bind="text: $data, click: $parents[1].click"
The updated code of 2nd edition is here: invoke context action in child event
来源:https://stackoverflow.com/questions/18138379/how-to-access-parent-or-parents-in-knockout-viewmodel-click-event