How can I partially display the observed array with the "Show more ..." button

I would like to add a list of options to the page from a knockout observableArray. When more than a custom number of items are displayed, you must display the "More options ..." button (or link). Pressing this button should display all the elements and change the button text to "Smaller options". To make it more interesting: the button should only be displayed if there is more than one item to be hidden.

Below is the code (see this script ), but there is no cleaner or more general solution (for example, using user binding)?

<ul data-bind="foreach: options"> <li data-bind="visible: $root.showMore() || $index() < $root.showMoreCount() || $root.options().length <= $root.showMoreCount()+1, text: $data"></li> </ul> <a data-bind="visible: options().length-1 > showMoreCount(), text: showMore() ? 'Less options' : 'More options', click: function () { showMore(!showMore()) }"></a> 
+4
source share
1 answer

You can write a custom observable function to include all of your functions:

 ko.showMoreArray = function(initial) { var observable = ko.observableArray(initial); //observables to change behaviour observable.limit = ko.observable(3).extend({numeric:true}); observable.showAll = ko.observable(false); //function to toggle more/less observable.toggleShowAll = function() { observable.showAll(!observable.showAll()); }; //computed observable for filtered results observable.display = ko.computed(function() { if (observable.showAll()) { return observable(); } return observable().slice(0,observable.limit()); }, observable); return observable; }; 

It really just wraps up what you already wrote, but it is reusable and leaves your HTML much neat:

 <input data-bind="value: $root.orders.limit, valueUpdate: 'afterkeyup'" /><br/> <ul data-bind="foreach: orders.display"> <li data-bind="text: $data"></li> </ul> <a data-bind="text: orders.showAll() ? 'Less options' : 'More options', click: orders.toggleShowAll" href="#"></a> 

I put the working version on jsFiddle .

In the above example, you need to bind to the display property in the original array, but otherwise it will behave like a β€œfull” array to all of your code (which I think makes more sense overall). However, if you prefer it to behave as a filtered (i.e. a maximum of 3 elements) array to your code, then you can achieve this in the same way as shown here

+7
source

Source: https://habr.com/ru/post/1484823/


All Articles