You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Promise对象绑定Polymer模板的dom-repeat?

Handling Promises with Polymer's dom-repeat and Dropdowns

Hey there! Let's work through how to bind Promise-based data (like what you get from Firestore) to Polymer's dom-repeat and dropdown elements. I've dealt with this exact scenario before, so here's a step-by-step breakdown with code examples.

First, a core concept to keep in mind: Polymer's template system doesn't natively resolve Promises directly in bindings. The fix? Resolve the Promise first, then assign the result to a reactive Polymer property—since Polymer automatically updates the UI when reactive properties change.

1. Binding Firestore Data to dom-repeat

Here's how to fetch data from Firestore (via a Promise) and bind it to dom-repeat:

Step 1: Define Reactive Properties

In your Polymer element, declare a property to hold the Firestore data. This property needs to be reactive so Polymer can track changes and update the UI.

Step 2: Fetch Data and Resolve the Promise

In the element's connectedCallback (or a custom method), call Firestore's API, resolve the Promise, and assign the parsed data to your reactive property.

Full Code Example (Element + Template)

JavaScript

class FirestoreListElement extends Polymer.Element {
  static get is() { return 'firestore-list-element'; }
  
  static get properties() {
    return {
      // Reactive property to hold Firestore items
      firestoreItems: {
        type: Array,
        value: () => [] // Default empty array to avoid null errors
      }
    };
  }

  connectedCallback() {
    super.connectedCallback();
    this.loadFirestoreData(); // Trigger data fetch when element connects to DOM
  }

  loadFirestoreData() {
    // Call Firestore collection (returns a Promise)
    firebase.firestore().collection('your-collection-name').get()
      .then(querySnapshot => {
        // Convert Firestore snapshot to an array of usable objects
        const items = querySnapshot.docs.map(doc => ({
          id: doc.id,
          ...doc.data() // Spread all document fields into the object
        }));
        // Assign to reactive property to trigger UI update
        this.firestoreItems = items;
      })
      .catch(error => {
        console.error('Failed to load Firestore data:', error);
        // Add user-facing error handling here if needed
      });
  }
}

customElements.define(FirestoreListElement.is, FirestoreListElement);

HTML Template

<dom-module id="firestore-list-element">
  <template>
    <h2>My Firestore Items</h2>
    <!-- Bind dom-repeat to the reactive property -->
    <div class="item-list">
      <dom-repeat items="[[firestoreItems]]">
        <template>
          <div class="item-card">
            <h3>[[item.title]]</h3>
            <p>[[item.description]]</p>
          </div>
        </template>
      </dom-repeat>
    </div>
  </template>
</dom-module>

2. Binding Firestore Data to a Dropdown

For dropdowns (like paper-dropdown-menu or native <select>), the approach is nearly identical: resolve the Promise to get options, assign to a reactive property, then bind that property to the dropdown's items.

Example with paper-dropdown-menu

Update the Element's Properties and Methods

Add a reactive property for dropdown options, plus a method to fetch them:

static get properties() {
  return {
    firestoreItems: { /* ... existing property ... */ },
    dropdownOptions: {
      type: Array,
      value: () => []
    },
    selectedOption: {
      type: String,
      notify: true, // Let parent elements track selection changes
      reflectToAttribute: true
    }
  };
}

connectedCallback() {
  super.connectedCallback();
  this.loadFirestoreData();
  this.loadDropdownOptions(); // Fetch dropdown options on element load
}

loadDropdownOptions() {
  firebase.firestore().collection('dropdown-options').get()
    .then(querySnapshot => {
      this.dropdownOptions = querySnapshot.docs.map(doc => ({
        label: doc.data().displayName, // Text users will see in the dropdown
        value: doc.id // The underlying value to track for selections
      }));
    })
    .catch(error => {
      console.error('Failed to load dropdown options:', error);
    });
}

Update the Template

Add the dropdown, using dom-repeat to render options:

<template>
  <!-- ... existing dom-repeat section ... -->

  <h3>Select an Option</h3>
  <paper-dropdown-menu label="Choose an Item">
    <paper-listbox slot="dropdown-content" selected="{{selectedOption}}">
      <dom-repeat items="[[dropdownOptions]]">
        <template>
          <paper-item value="[[item.value]]">[[item.label]]</paper-item>
        </template>
      </dom-repeat>
    </paper-listbox>
  </paper-dropdown-menu>
</template>

Key Notes to Remember

  • Never bind a Promise-returning function directly to dom-repeat or dropdown items (e.g., <dom-repeat items="[[loadFirestoreData()]]">). This causes repeated, unnecessary API calls and won't resolve the Promise for the UI.
  • Stick to reactive properties: Polymer's reactivity system is what triggers UI updates when your data changes.
  • Real-time updates: If you want the UI to auto-update when Firestore data changes, use onSnapshot() instead of get():
    loadFirestoreData() {
      firebase.firestore().collection('your-collection-name')
        .onSnapshot(querySnapshot => {
          const items = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
          this.firestoreItems = items;
        }, error => {
          console.error('Snapshot error:', error);
        });
    }
    
    This sets up a listener that updates your property every time the collection changes.

内容的提问来源于stack exchange,提问作者Raj T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:17:51