Source: src/js/views/maps/viewfinder/PredictionsListView.js

"use strict";
define([
  "backbone",
  "views/maps/viewfinder/PredictionView",
  "models/maps/viewfinder/ViewfinderModel",
], (Backbone, PredictionView, ViewfinderModel) => {
  // The base classname to use for this View's template elements.
  const BASE_CLASS = "viewfinder-predictions";

  /**
   * @class PredictionsListView
   * @classdesc PredictionsListView manages a list of autocomplete
   * predictions that can be selected by the user.
   * @classcategory Views/Maps
   * @name PredictionsListView
   * @extends Backbone.View
   * @screenshot views/maps/viewfinder/PredictionsListView.png
   * @since 2.28.0
   * @constructs PredictionsListView
   */
  var PredictionsListView = Backbone.View.extend(
    /** @lends PredictionsListView.prototype */ {
      /**
       * The type of View this is
       * @type {string}
       */
      type: "PredictionsListView",

      /**
       * The HTML class to use for this view's outermost element.
       * @type {string}
       */
      className: BASE_CLASS,

      /**
       * The HTML element to use for this view's outermost element.
       * @type {string}
       */
      tagName: "ul",

      /**
       * @typedef {Object} ViewfinderViewOptions
       * @property {ViewfinderModel} The model associated with the parent view.
       */
      initialize({ viewfinderModel }) {
        this.children = [];
        this.viewfinderModel = viewfinderModel;

        this.setupListeners();
      },

      /** Setup all event listeners on ViewfinderModel. */
      setupListeners() {
        this.listenTo(this.viewfinderModel, "change:predictions", () => {
          this.render();
        });

        this.listenTo(this.viewfinderModel, "selection-made", (newQuery) => {
          if (this.viewfinderModel.get("query") === newQuery) return;

          this.clear();
        });
      },

      /**
       * Remove all child view elements and destroy their Backbone.View.
       */
      clear() {
        while (this.children.length) {
          this.children.pop().remove();
        }
      },

      /**
       * Render the Prediction sub-views, tracking
       * them so they can be removed and their event listeners
       * cleaned up.
       */
      render() {
        this.clear();
        this.children = this.viewfinderModel
          .get("predictions")
          .map((prediction, index) => {
            const view = new PredictionView({
              index,
              predictionModel: prediction,
              viewfinderModel: this.viewfinderModel,
            });
            view.render();
            return view;
          });

        this.$el.html(this.children.map((view) => view.el));
      },
    },
  );

  return PredictionsListView;
});