KO Binding events to a component parentElement
by Kevin Van Lierde
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<h3>Test for <code data-bind="text: test"></code></h3><br><br>
<custom-button params="msg: myMsg, label: label"></custom-button>
<br><br><br>
<input type="text" data-bind="value: myMsg">
<template id="custom-button-tmpl">
<button type="button" data-bind="text: label"></button>
</template>
CSS
custom-button, .custom-button {
border: 1px solid black;
padding: 1rem;
cursor: pointer;
}
h3 {font-weight: normal }
JavaScript
var options = ['createViewModel','Custom templateLoad','ko.bindingProvider.instance.preprocessNode'],
test = 2,
customButtonComponent = { // test component
viewModel: customButton,
template: { element: 'custom-button-tmpl'}};
function customButton(params) {
var self = this;
this.msg = params.msg;
this.label = params.label;
this.someProp = true;
}
switch (options[test]) {
case 'createViewModel':
customButtonComponent.viewModel = { createViewModel: function(params, componentInfo) {
var element = componentInfo.element,
// access to viewModel the component is rendered in
data = ko.dataFor(element),
// access to the $context variable, in this case === $root and $data
context = ko.contextFor(element),
// access to component params and name
compInfo = ko.bindingProvider.instance.getBindings(element, context);
$(element).on('click', function() { confirm(params.msg())});
return new customButton(params);
}};
break;
case 'Custom templateLoad':
customButtonComponent.template.beforeRender = function(html) {
var container = $('<div></div>'),
btn = $(html);
btn.attr('data-bind', btn.attr('data-bind') + ', click: function() { confirm(msg()) },');
container.append(btn).append('<code data-bind="text: someProp"></code>');
return container.html();
};
var templateLoader = { loadTemplate: function(name, templateConfig, callback) {
if (templateConfig.beforeRender) {
var template = typeof templateConfig === 'string' ? templateConfig :
(templateConfig.element ? document.getElementById(templateConfig.element).innerHTML : templateConfig);
template = templateConfig.beforeRender(template);
...