简体   繁体   中英

How to use list.js with Hot Towel Template

I am working with the Hot Towel Template and I'm trying to use list.js to filter results in a list.

I have included the list.min.js file in my bundle config and I have also referenced it in the index.html file correctly.

I have a view (leads.html) that looks like this:

<div id="lead-article-list">
    <input class="search" type="text" />
    <ul class="list" data-bind="foreach: leads" >
        <li>
            <span data-bind="text: name" class="name"></span>
        </li>
        <li>
            <span data-bind="text: description" class="description"></span>
        </li>
    </ul>
</div>
<script type="text/javascript">
    var options = {
        valueNames: ['name', 'description']
    };
    var featureList = new List('lead-article-list', options);
</script>

and then I have a corresponding viewModel (leads.js) that looks like this:

define(['services/datacontext', 'durandal/plugins/router'],
    function (datacontext, router) {
        var leads = ko.observableArray();
        var activate = function () {
            return datacontext.getLeadArticles(leads, false);
        };
        var vm = {
            activate: activate,
            leads: leads
        };
        return vm;
    });

When I run the application my list populates correctly, but when I type anything into the search input, no filtering occurs. I feel like I am missing something specific to KnockoutJS and the fact that I'm working with observables.

I'm also not sure if the script at the end of my view should really be somewhere in my viewmodel?

Any help would be greatly appreciated. Thanks!

The <script> tag in leads.html will be ignored during composition. On a side note make sure that HTML fragments have a single root element otherwise Durandal will wrap them in a div , which is not always what might be intended ( http://durandaljs.com/documentation/Creating-A-View/ ). So the html fragment should become something like the following.

<div id="lead-article-list">
    <input class="search" type="text" />
    <ul class="list" data-bind="foreach: leads" >
        <li>
            <span data-bind="text: name" class="name"></span>
        </li>
        <li>
            <span data-bind="text: description" class="description"></span>
        </li>
    </ul>
</div>

I'd suggest moving the script content into the viewAttached callback. viewAttached will provide the composed view as argument, but it doesn't guaranty that view is attached to the DOM only to the parent node. So you have to give something like the following a try to see if that's sufficient for list.js.

define(['services/datacontext', 'durandal/plugins/router'],
    function (datacontext, router) {
        var leads = ko.observableArray();
        var activate = function () {
            return datacontext.getLeadArticles(leads, false);
        };
        var viewAttached = function(view){
             var options = {
                valueNames: ['name', 'description']
            };
            var featureList = new List(view, options);
        };
        var vm = {
            activate: activate,
            leads: leads,
            viewAttached: viewAttached
        };
        return vm;
    }
);

Plan B : On a quick glance http://listjs.com/ seems to be optimized for converting plain lists/tables while leads is a ko.observableArray() that gets populated by datacontext.getLeadArticles , so it might be better to move the handling of sorting/filtering/paging to the datacontext . That would have the additional advantage that the datacontext could offload the functionality to the server side if there are larger data sets involved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM