Monaca Onsen UI Discord Chat Github Repo

searchable list with lazy-repeat



  • In my Angular js app I have a searchable ons-list with ng-repeat directive defined as follows

    <ons-list>
      <ons-list-item bindonce ng-repeat="item in itemsList|filter:search track by item.id" >
    {{name}} 
    </ons-list-item>
    </ons-list>
    

    I want to use ons-lazy-repeat to improve performance - the question is, how do I make the list with lazy-repeat searchable as above?
    Thanks
    Andy


  • administrators

    You can do something like this:

    <ons-page ng-controller="ListController as list">
      <ons-list>
        <ons-list-item ons-lazy-repeat="list.delegate">{{ item }}</ons-list-item>
      </ons-list>
    </ons-page>
    

    And then assuming you have your search results in itemList:

    ons.bootstrap()
      .controller('ListController', function() {
        this.delegate = {
          configureItemScope: function(index, itemScope) {
            if (index < itemList.length) {
              itemScope.item = itemList[index];
            }
          },
          countItems: function() {
            return itemList.length;
          }
        };
      });
    

    This assumes that you can get all your search results first before showing them. If you are lazily getting the search results (like calling a server for results page by page) then you would need to change configureItemScope to check if you had already displayed all the results you currently have and if so then call the server for more results.

    By the way, this is based off the ons-lazy-repeat tutorial https://onsen.io/playground/?framework=angular1&category=reference&module=lazy-repeat



  • I forgot to mention that In the current implementation there is a search row defined as follows

     <div class="search-row">
     <input type="search" placeholder="Search Items"  ng-model="search" />
     </div>
    

    So when user starts typing in the input field
    this line

    ng-repeat="item in itemsList|filter:search track by item.id" 
    

    handles displaying only items that match the search criteria
    If I understand you correctly with lazy-repeat I will have to do this myself in the controller, i.e intercept user entering characters and fill the itemsList accordingly?
    Thanks
    Andy


  • administrators

    Yes, but it should be a straightforward change.

    First you can add ng-change to your input:

     <input type="search" placeholder="Search Items"  ng-model="search" ng-change="updateResults()" />
    

    Then inject $filter and create a method to filter itemList:

    $scope.updateResults = function() {
      filteredList = $filter('filter')(itemList, // whatever
    }
    

    And also change delegate.configureItemScope to use filteredList instead of itemList.



  • Great, Thank you!
    I’ll give it a try as soon as I get lazy-repeat to work… discussed in another post.