Unable to get md-virtual-repeat to work within md-select?

Attempting to use md-select to showcase a large amount of data is causing the browser to freeze upon opening. To address this, I tried implementing md-virtual repeat within md-select for improved performance. However, the code doesn't seem to be functioning as expected. Is there an error in my approach?

<md-input-container flex>
  <label>test</label>
  <md-select ng-model="$ctrl.haha">
    <md-virtual-repeat-container id="vertical-container">
      <md-option md-virtual-repeat="item in ctrl.infiniteItems" md-on-demand ng-value="item" ng-selected="$first">
        {{item}}
      </md-option>
    </md-virtual-repeat-container>
  </md-select>
</md-input-container>

#vertical-container {
  height: 256px;
}

this.infiniteItems = {
  numLoaded_: 0,
  toLoad_: 0,
  items: [],

  // Required.
  getItemAtIndex(index) {
    if (index > this.numLoaded_) {
      this.fetchMoreItems_(index);
      return null;
    }
    return this.items[index];
  },

  // Required.
  getLength() {
    return this.numLoaded_ + 5;
  },

  fetchMoreItems_(index) {
    if (this.toLoad_ < index) {
      this.toLoad_ += 20;
      for (let i = 0; i < 10000; i++) {
        this.items.push(i);
      }
      this.numLoaded_ = this.toLoad_;
    }
  }
};

Answer №1

To ensure that this combination works properly, it is important to keep your virtual-repeat-container in sync. You can achieve this by implementing a simple 'refresh' function that is triggered when the select element is opened:

function () {
    return $timeout(function () {
        $scope.$broadcast("$md-resize");
    }, 100);
};

This should be sufficient to maintain synchronization. For example, refer to the working code snippet below:

angular.module("app", ["ngMaterial", "ngSanitize", "ngAnimate"])
  .controller("MainController", function($scope, $timeout) {

    // refresh virtual container
    $scope.refresh = function() {
      return $timeout(function() {
        $scope.$broadcast("$md-resize");
      }, 100);
    };

    $scope.infiniteItems = {
      _pageSize: 10000,
      toLoad_: 0,
      items: [],

      getItemAtIndex(index) {
        if (index > this.items.length) {
          this.fetchMoreItems_(index);
          return null;
        }
        return this.items[index];
      },

      getLength() {
        return this.items.length + 5;
      },

      fetchMoreItems_(index) {
        if (this.toLoad_ < index) {
          this.toLoad_ += this._pageSize;

          // simulate $http request
          $timeout(angular.noop, 300)
            .then(() => {
              for (let i = 0; i < this._pageSize; i++) {
                this.items.push(i)
              }
            });
        }
      }
    };

  });
#vertical-container {
  height: 256px;  
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>select with md-virtual-repeat</title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-aria.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-sanitize.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.min.js"></script>
  </head>
  <body>
    <div class="main" ng-app="app" ng-controller="MainController" layout="column" layout-align="center center" layout-fill>
      <md-input-container>
        <label>Select an option</label>
        <md-select ng-model="haha" md-on-open="refresh()">
          <md-virtual-repeat-container id="vertical-container">
            <md-option md-virtual-repeat="item in infiniteItems" md-on-demand="" ng-value="item" ng-selected="haha==item">{{item}}</md-option>
          </md-virtual-repeat-container>
        </md-select>
      </md-input-container>
    </div>
    </script>
  </body>

</html>

For more information, you may want to refer to a similar answer posted here.

Answer №2

In a post on https://github.com/angular/material/issues/10868, it was mentioned that the behavior of different versions of angularjs varies. The updated $timeout function now includes the statement

window.dispatchEvent(new Event('resize'));
.

Here is how the final $timeout function looks:

return $timeout(function() {
   $scope.$broadcast("$md-resize");
   window.dispatchEvent(new Event('resize'));
}, 100);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

animation of leaping to a specific element

I am currently working on a sidebar with links that have a hover effect to add a bullet. However, I want the bullet to smoothly follow the cursor's movement along the y-axis within the sidebar instead of jumping between the links. How can I achieve th ...

The manner in which sessionStorage or localStorage is shared between different domains

I am looking to persist data across different domains using sessionStorage or localStorage. How can I achieve this? The data needs to be shared between a Vue project and a React project. English is not my strong suit, so I hope you are able to understand ...

The issue of ERR_MODULE_NOT_FOUND in Node.js express.Router arises when attempting to import new routes

Something strange is happening. I was in the process of organizing my routes by creating a new folder. Within this folder, I used the express.Router API to define the routes and then exported the router itself. Here is an example code snippet from my pos ...

Using setTime in JavaScript allows for customizing and adjusting the

I'm having trouble getting this code to display the time. I thought it would work, but it's not showing the time. Can someone please help me figure out what's going wrong? function startTime() { var currentTime = new Date(); ...

Is it possible to retrieve the HttpsError status from a Firebase function?

Within my firebase function, I deliberately throw an error with a specific status and message using the following code: throw new functions.https.HttpsError('permission-denied', 'Token does not match'); When I receive the server respo ...

Using a React button to sort through an array

Hey there, I'm currently working on an app that filters a list based on user input. The idea is to click on buttons to exclude users with specific letters in their names. However, the code I have right now isn't functioning properly. Any assistan ...

Creating a header upon clicking a link

Is it feasible to establish a request header when a user clicks on a link? ...

Switch out a character with its corresponding position in the alphabet

Starting out, this task seemed simple to me. However, every time I attempt to run the code on codewars, I keep getting an empty array. I'm reaching out in hopes that you can help me pinpoint the issue. function alphabetPosition(text) { text.split ...

A guide to retrieving the types of optional properties within a class or interface using Typescript

class Data { ID: number; Activity?: string; public getDataType(name: string) { return typeof this[name]; } constructor() { } } let _data = new Data() _data.ID = 5 console.log(_data.getDataType("ID")) // Retu ...

Prevent legend strike-through on click in Vue Chart.js

Recently, I made the transition from vue 2 to vue 3 on my website and part of that process involved updating vue-chartjs and chartjs too. However, after modifying the legend text of my pie chart using the generateLabels option (as seen below), the striket ...

Enhancing the efficiency of a Puppeteer web scraping operation

app.get("/home", async (req, res) => { try { const browser = await puppeteer.launch(); const page = await browser.newPage(); const pageNumber = req.query.page || 1; await page.goto(`https://gogoanimehd.io/?page=${pageNumber ...

When working with AngularJS routing, utilize a function for the templateUrl to dynamically load the appropriate template

Can a function be used as the templateUrl in angularjs routing? The $routeProvider official documentation states: templateUrl – {string=|function()=} Check out the $routeProvider official documentation here In javascript, a function is typically def ...

Choose the initial unordered list within a specific division through Jquery

In a div, there is a ul. Inside a li, there is another ul. The task is to select only the first ul inside the div using jQuery. The HTML markup: <div class="parent"> <div class="clearfix"> <div class="another-div"> <ul cl ...

Disappearing Data in Chart.js When Window is Resized

I am utilizing the Chart.js library to present a line chart in a div that is enclosed within a <tr>. <tr class="item">...</tr> <tr class="item-details"> ... <div class="col-sm-6 col-xs-12 chart-pane"> <div clas ...

Mapping prop passed to client component in NEXT 13: A step-by-step guide

Hello, I'm currently navigating through the Next 13 APP directory and have encountered a scenario where everything functions smoothly when I integrate the server component as shown below: const Tasks = async () => { const { tasks } = await getAll ...

Flexbox causing issues with relative positioning at the bottom of the screen in various browsers

My flex component looks like this: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" ... width="100%" height="100%" creationComplete="init()"> ....... <components:Naviga ...

Error: Trying to access the 'title' property of an undefined variable in Vue.js

Creating a replica of hackernews by utilizing the axios API. The NewItem.vue component is not receiving any data, resulting in an error — TypeError: Cannot read property 'title' of undefined. Can you identify what's causing this issue in t ...

Utilizing optional parameters with React Router

Imagine I have a page at http://www.example.com/page/#/search set up with the following routing: <Router history={hashHistory}> <Route path='/search/' component={SearchPage} /> </Router> When a user performs a search using t ...

Guide on enabling users to input slide number and URL address to load content using Ajax

Is there a way to customize the number of slides in a slider and choose which content is loaded into each slide using AJAX calls in jQuery? Currently, my slider uses the jQuery .load() method to dynamically load content into each slide when it becomes vis ...

Is there a way to automatically close the Foundation topbar menu when a link is selected?

On my single page website, I am utilizing Zurb Foundation's fixed topbar which includes anchor links to different sections of the page. My goal is to have the mobile menu close automatically whenever a link inside it is clicked. As it stands now, whe ...