Reputation: 759
My binding handler adds a hyperlink to a list item tag. I would like to know how to attach click event to the hyperlink through the binding handler. The click event should call a function within the view model.
You can see code in this jsfiddle.
So my question is: How to attach an event handler to call showSectionName from the view model? Maybe using something like ko.bindingHandlers.click(...)
?
$(function () {
ko.bindingHandlers.bootstrapHyperlink = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var elt = "<a href='#'>" + viewModel.name + "</a>";
$(element).append(elt);
}
};
var Section = function (id, name) {
var self = this;
self.id = id,
self.name = name
};
self.showSectionName = function (data) {
alert("You clicked the section " + data.name);
}
function viewModel() {
var self = this;
self.Sections = ko.observableArray([
new Section(1, "Section 1"),
new Section(2, "Section 2"),
new Section(3, "Section 3")
])
}
ko.applyBindings(new viewModel());
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div style="width:200px">
<ul class="nav nav-pills nav-stacked" data-bind="foreach:Sections">
<li role="presentation" data-bind="bootstrapHyperlink: {click: showSectionName($data)}">
</li>
</ul>
</div>
Upvotes: 1
Views: 707
Reputation: 7308
You can try this,
I hope this is more like what you were after: JSFiddle
<div style="width:200px">
<ul class="nav nav-pills nav-stacked" data-bind="foreach:Sections">
<li role="presentation" data-bind="bootstrapHyperlink: name"></li>
</ul>
</div>
$(function () {
ko.bindingHandlers.bootstrapHyperlink = {
init: function (element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
var elt = "<a href='#'>" + value + "<span class='badge'></span></a>";
$(element).append(elt);
$(element).on('click', function () {
alert($(this).text());
});
}
}
Section = function (id, name) {
var self = this;
self.id = id,
self.name = name
};
function viewModel() {
var self = this;
self.Sections = ko.observableArray(
[
new Section(1, "Section 1"),
new Section(2, "Section 2"),
new Section(3, "Section 3")]);
self.showSectionName = function (data) {
alert("You clicked the section " + data.name);
}
}
var vm = new viewModel();
ko.applyBindings(vm);
});
Upvotes: 1
Reputation: 338208
There is no need for advanced techniques like custom binding handlers for your problem.
You ought not to build HTML with jQuery when you use knockout. Knockout builds all your HTML for you. Consider this simple example:
function Section(id, name) {
this.id = id;
this.name = name;
}
Section.prototype.showSectionName = function () {
alert("You clicked '" + this.name + "'");
}
function ViewModel() {
var self = this;
self.sections = ko.observableArray([
new Section(1, "Section 1"),
new Section(2, "Section 2"),
new Section(3, "Section 3")
]);
}
$(function () {
ko.applyBindings(new ViewModel());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:200px">
<ul class="nav nav-pills nav-stacked" data-bind="foreach: sections">
<li role="presentation">
<a href="#" data-bind="text: name, click: showSectionName"></a>
</li>
</ul>
</div>
Note that using the prototype
only works for regular functions, not for knockout's computed
values.
Upvotes: 2
Reputation: 43881
See here for ko.utils.registerEventHandler
But it also looks like this might be a good use for ko.components.
Upvotes: 1