Reputation: 12809
I have let's say a viewmodel for querying products, similar to this.
function ProductQueryModel() {
this.publishedSince = ko.observable();
this.nameContains = ko.observable();
...
this.SubmitQuery = function() {
// what shall I do? ...
}
}
Now I create a template
for this viewmodel, so that I can reuse is in the application.
<template id="productquerymodel-template">
<form>
...
<input type="text" data-bind="textInput: nameContains"/>
...
<button type="submit" data-bind="click: SubmitQuery">Submit</button>
</form>
</template>
I intentionally didn't use the submit
binding, because in most cases I want frm submission only on button click to prevent accidental submission for example.
Here I have a problem with submitting the form. The method which is bound to the submit button's click
event doesn't make sense inside the query model, because the query model itself has no idea what to do when querying. It should be outside of the query viewmodel, because the method implementation depends on what exactly is using the query model.
But on the other hand, containing the submit button inside the template makes sense, because it's part of the form.
A way would be to define the click
binding inside the template
like $parent.SubmitQuery.bind($parent)
, but then I would restrict the consumer of the template to always define a SubmitQuery
function on the parent of the query model, which is not a nice solution I think.
Does anybody know about an existing practice for such scnearios, or any other ideas which might help in these situations?
Upvotes: 0
Views: 70
Reputation: 961
Here is how I would accomplish that.
Template file:
<script type="text/html" id="productquerymodel-template">
<form>
<input type="text" data-bind="textInput: nameContains"/>
<button type="submit" data-bind="click: SubmitQuery">Submit</button>
</form>
</script>
<script>
function ProductQueryModel() {
var self = this;
self.publishedSince = ko.observable();
self.nameContains = ko.observable();
self.SubmitQuery = function () {
// Do nothing by default
};
}
</script>
HTML page:
<div data-bind="template: {
name: 'productquerymodel-template',
data: ProductQuery
}"></div>
<script>
// This would be your main view model for the page
function MainViewModel() {
var self = this;
self.ProductQuery = new ProductQueryModel()
}
// Initialize an instance of the view model
var vm = new MainViewModel();
// Insert your page specific SubmitQuery function here
vm.ProductQuery.SubmitQuery = function () {
alert('Page specific stuff');
};
ko.applyBindings(vm);
</script>
Fiddle link: https://jsfiddle.net/dw1284/fopwgf4a/
Upvotes: 1