简体   繁体   中英

How to get element in dom-if or dom-repeat?

<dom-module id="weather-data">
<template>
  <style is="custom-style" include="iron-flex iron-flex-alignment">


 :host {
      display: block;
      font-family: Roboto;
    }

    paper-progress {
      top: 0;
      left: 0;
      position: fixed;
      width: 100%;
      --paper-progress-active-color: var(--paper-light-blue-500);
      --paper-progress-secondary-color: var(--paper-light-blue-100);
    }

    paper-icon-button {
      margin: 0 auto;
      margin-top: 20px;
      display: block;
    }

    #weatherIcon {
      width: 200px;
      height: 200px;
    }

    table {
      border-collapse: collapse;
    }

    table td {
      text-align: center;
      border: 1px solid #006064;
      padding: 5px;
    }

  </style>

  <paper-progress
    id="request-progress"
    indeterminate
    hidden$="[[!activeRequest]]">
  </paper-progress>

  <iron-ajax
    id="getData"
    auto
    url="[[weatherApiUrl]]"
    handle-as="json"
    last-response="{{weatherResponse}}"
    last-error="{{error}}"
    params="[[_getGegevensVanLocatie(coordinaten.latitude,        coordinaten.longitude)]]"
    loading="{{activeRequest}}">
  </iron-ajax>

  <template is="dom-if" id="tmp" if="[[weatherResponse]]">
    <paper-icon-button
    id="location-button"
    disabled$="{{disableLocationButton}}"
    on-tap="_getLocation"
    icon="maps:my-location"
    alt="Zoek mijn huidige locatie">
    </paper-icon-button>

    <div>
      <div class="horizontal center-justified layout">
        <h2>Weer voor locatie: <span>[[_maakLocationString(weatherResponse.query.results.channel.location)]]</span></h2>
      </div>
      <div class="horizontal center-justified layout">

        <iron-icon
          id="weatherIcon"
          icon="[[_getIcon(weatherResponse.query.results.channel.item.condition.code)]]">
        </iron-icon>

      </div>
      <div class="horizontal center-justified layout">
        <h2>
          <span>
            [[weatherResponse.query.results.channel.item.condition.text]],
            [[weatherResponse.query.results.channel.item.condition.temp]]° [[weatherResponse.query.results.channel.units.temperature]]
          </span>
        </h2>
      </div>
      <div class="horizontal center-justified layout">
        <table>
          <tr>
            <td>
              <iron-icon icon="icons:arrow-upward"></iron-icon>
            </td>
            <td>
              <iron-icon icon="icons:arrow-downward"></iron-icon>
            </td>
          </tr>
          <tr>
            <td>[[weatherResponse.query.results.channel.astronomy.sunrise]]</td>
            <td>[[weatherResponse.query.results.channel.astronomy.sunset]]</td>
          </tr>
        </table>
      </div>
      <div class="horizontal center-justified layout">
        <h5 id="update-time">
          Gegevens geraadpleegd om: [[weatherResponse.query.results.channel.item.condition.date]]<span></span>
        </h5>
      </div>
    </div>
  </template>
</template>

<script>


    Polymer({
        is: 'weather-data',
        properties: {
            weatherApiUrl: {
                type: String,
                value: "https://query.yahooapis.com/v1/public/yql"
            },
            coordinaten: {
                type: Array,
                value: {
                    longitude: 22,
                    latitude: 22
                }
            }
        },
        ready: function() {
            if (navigator.permissions && navigator.permissions.query) {
                navigator.permissions.query({
                    name: 'geolocation'
                }).then(function(status) {
                    if (status.state === 'granted') {
                        console.log("Permisson already granted");
                        _getLocation();
                    } else {
                        console.log("Location not YET granted, using default coordinates");
                        if (status.state === "denied") {
                            console.log("Denied");
                        }
                    }
                });
            } else {
                console.log("Permission not available");
                console.log("Using standard coordinates");
            }
        },
        _getLocation: function() {
            console.log("Getting location");
        },
        _getGegevensVanLocatie: function(latitude, longitude) {
            var latLong = '(' + 51.0339 + ',' + 3.7094 + ')';
            return {
                format: 'json',
                q: 'select * from weather.forecast where woeid in ' +
                    '(select woeid from geo.places(1) where text="' + latLong + '") and u="c"'
            };
        },
        _maakLocationString: function(location) {
            if (location.city && location.region) {
                return location.city + ', ' + location.region;
            } else {
                return location.city || 'Onbekend';
            }
        },
        _getIcon: function(code) {
            if (code >= 37 || code <= 12) {
                return "image:flash-on";
            }

            if (code <= 18) {
                return "image:flare";
            }

            if (code <= 30) {
                return "image:wb-cloudy";
            }

            return "image:wb-sunny";
        }
    })
</script>

So this is my code. What I'm trying to do is get the <paper-icon-button> element when the permission is granted on the navigator when the state is changed to granted. However this does not work with this.$.location-button or with this.$$('#location-button) .

Is this because I use it in the ready() function?

The Polymer docs for Automated Node Finding state:

Note: Nodes created dynamically using data binding (including those in dom-repeat and dom-if templates) are not added to the this.$ hash. The hash includes only statically created local DOM nodes (that is, the nodes defined in the element's outermost template).

So in your case, you have to query for the button with this.$$('#location-button') instead of using this.$['location-button'] .

I'm assuming the Boolean weatherResponse is false when you query for #location-button , in which case the button would not exist in the DOM. If you set the Boolean to true in ready() , you'd have to wait for the button to be stamped in the next render (with Polymer.RenderStatus.afterNextRender() ) before querying for it:

ready: function() {
  this.weatherResponse = true;
  Polymer.RenderStatus.afterNextRender(this, () => {
    console.log(this.$$('#location-button'));
  });
}

codepen

The dom-if template stamps its contents into the DOM only when its if property becomes truthy. Once the content has been stamped it only hides and shows the content when the if property changes. Though setting restamp to true destroys and creates the content anew.

Therefore you cannot locate your paper-icon-button before you have fetched your weatherResponse which it has not done in your element ready lifecycle callback.

Note that in the docs for polymers conditional templates usage it says:

Since it is generally much faster to hide and show elements rather than destroy and recreate them, conditional templates are only useful to save initial creation cost when the elements being stamped are relatively heavyweight and the conditional may rarely (or never) be true in given usages. Otherwise, liberal use of conditional templates can actually add significant runtime performance overhead.

So perhaps changing your dom-if template into a element (eg div ) with a hidden$="[[!weatherResponse]]" attribute would be more appropriate in your case. This would also have the paper-icon-button be stamped when ready is called.

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