I have an knockout observable array of activities which contains audits and ments. I've got the data from the server and sorted the array of activities based on the timestamp of the objects.
I'd like to be able to conditionally display html based on the type, so audits and ments will look different.
<!-- ko foreach: activities -->
<div class="audit" data-bind="visible: {activity is typeof Audit}">
@*Do some audit html*@
</div>
<div class="ment" data-bind="visible: {activity is typeof Comment}">
@*Do some ment html*@
</div>
<!-- /ko -->
I've got the following html but I don't know how do the condition, I just wrote something in above as a placeholder so you get the idea of what I'm trying to achieve.
I'm probably approaching this all wrong, any help much appreciated!
I have an knockout observable array of activities which contains audits and ments. I've got the data from the server and sorted the array of activities based on the timestamp of the objects.
I'd like to be able to conditionally display html based on the type, so audits and ments will look different.
<!-- ko foreach: activities -->
<div class="audit" data-bind="visible: {activity is typeof Audit}">
@*Do some audit html*@
</div>
<div class="ment" data-bind="visible: {activity is typeof Comment}">
@*Do some ment html*@
</div>
<!-- /ko -->
I've got the following html but I don't know how do the condition, I just wrote something in above as a placeholder so you get the idea of what I'm trying to achieve.
I'm probably approaching this all wrong, any help much appreciated!
Share Improve this question asked Jun 13, 2012 at 15:34 NeilNeil 5,2398 gold badges53 silver badges88 bronze badges 2-
I think
data-bind="visible: {activity.hasOwnProperty(<SOME UNIQUE FOR AUDIT PPOPERTY NAME HERE>)}"
will work but could you please provide a JS fiddle for testing? – Sergey Rybalkin Commented Jun 13, 2012 at 15:37 - I've never used js fiddle before but I'll try and get one going and then add as an edit. – Neil Commented Jun 13, 2012 at 15:42
2 Answers
Reset to default 3Nayjest's solution should work if you change the visible binding to an if binding - that way it won't try render the parts with the title dependency.
A better solution, however, is probably to have two templates and execute them based on the type. You could have a method on the VM that takes $data and returns, for example, 'auditTemplate' or 'mentTemplate' depending on the result of something like $data instanceof Audit. You would then have two templates embedded as script tags with those ids:
<script id="auditTemplate" type="text/html">
<div class="audit">
<!-- Do some audit stuff -->
</div>
</script>
<script id="mentTemplate" type="text/html">
<div class="ment">
<!-- Do some ment stuff -->
</div>
</script>
And then in your VM, you'd have something like:
this.getTemplate = function(data) {
return (data instanceof Audit) ? 'auditTemplate' : 'mentTemplate'
}
In your page's html you'd do something like:
<!-- ko foreach: activities -->
<div databind="template: {name:$parent.getTemplate($data), data: $data}"></div>
<!-- /ko -->
If you have class Audit that is visible in global scope and property 'activities' of view model, try something like this:
<div data-bind="foreach: activities">
<div data-bind="visible: $data instanceof Audit">
<h1 data-bind="text: $data.title"></h1>
<!-- Some other data here -->
</div>
</div>