Reputation: 2965
Searched all over stackoverflow & other sources - can't seem to find anything of much help.
I have a statistical table-like UI with data driven content. The data is a huge array/object serialised on the back-end.
I am then extracting the values within that array - which are set as observables - and outputting them on the page with data-bind attributes.
The table displays the top performing artist in a given category and the two related artists below.
The problem is that we need to dynamically change the data-bind attribute so that it is capable of looking at a variable property in the data.
For example, if the user filters by "Artist", we want to display the Artist's Name (i.e
<span data-bind="text: ArtistName()"></span>
BUT
if the user filters by "Genre", we want the same part of the HTML to be able to display the Track Length (or any other arbitrary observable property) (i.e )
Ultimately, I want to have a variable data-bind attribute, like
I know that I can achieve this using a potentially huge if statement, like so:
<!-- ko if: $parent.SortMethod() == 'Topic1' -->
<span data-bind="text: Topic1()"></span>
<!-- /ko -->
<!-- ko if: $parent.SortMethod() == 'Topic2' -->
<span data-bind="text: Topic2()"></span>
<!-- /ko -->
<!-- ko if: $parent.SortMethod() == 'Topic3' -->
<span data-bind="text: Topic3()"></span>
<!-- /ko -->
...etc
Surely there is a more efficient way...?
Upvotes: 2
Views: 133
Reputation: 49095
You'll have to bind the grid data to a function that will then return the data sorted / filtered by the desired field. Also, you'll have to bind that drop-down list to an observable in your view-model.
function GridModel(data)
{
var self = this;
self.RawData = data;
self.SortedBy = ko.observable();
self.GetGridData = function()
{
var ret = self.RawData();
var sortingFld = self.SortedBy();
if (sortingFld)
{
ret = ret.sort(function (a, b) {
a = ko.unwrap(a[sortingFld]);
b = ko.unwrap(b[sortingFld]);
return (a == b ? 0 : a < b ? -1 : 1) * 1;
});
}
return ret;
}
}
HTML:
<table class="grid">
<thead>
<th>Category</th>
<th>Artist</th>
<th>Track</th>
</thead>
<tbody data-bind="foreach: GetGridData()">
<td data-bind="text: Category"></td>
<td data-bind="text: Artist"></td>
<td data-bind="text: Track"></td>
</tbody>
</table>
The drop-down will then be able to change the SortedBy
observable and automatically refresh the grid accordingly:
<select data-bind="value: SortedBy, options: ['Artist', 'Track']"></select>
(The code above only demonstrates ascending sorting, but you can easily expand it for filtering as well).
Upvotes: 2