Parent element is ready before its child - Polymer

2019-07-14 19:55发布

问题:

This question had been modified to match the actual problem.

The original question mistakingly focused on iron-ajax, please see the original problem below. The question should have been:

Please advice why child iron-ajax element is not ready during the 'ready' callback of my-component defined as follows:

<dom-module id="my-component">
    <template>
        <link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
        <iron-ajax
            id="selectionLoader"
            url=""
            method="GET"
            handle-as="json"
            debounce-duration="300"
            last-response="{{ suggestedOptions }}"
            last-error="{{ lastError }}"
            verbose=true
        >
        </iron-ajax>
    </template>
</dom-module>

<script>
    (function () {
        Polymer({
            is : 'paper-select',
            ready : function() {
                console.log(this.$.selectionLoader.generateRequest); // undefined
            }
        })
    })()
</script>

Original question

Original title: 'WebComponentsReady' fires before iron-ajax ready - Polymer 1.0

I need to assign some values to an observed property of a custom component that internally uses iron-ajax with disabled auto - so I need to call .generateRequest on the iron-ajax element. This should happen when host page/component is ready, in order to fetch from the server some defaults based on data in the host component code.

selected is an array property on the component observed like this:

observers: [
    '_selectedChanged(selected.splices)' // _selectedChanged calls .generateRequest
]

The observer is triggered by:

window.addEventListener('WebComponentsReady', function() {
    document.querySelector('paper-select').selected = [{id : 11855},{id : 11856}];
});

The problem is that WebComponentsReady fires before .generateRequest is available on the iron-ajax. So my component is initialized, _selectedChanged is called, but iron-ajax inside it is missing the method and in fact other properties/methods as well.

I've implemented a "deferred" workaround using setTimeout inside the component and it works like charm but it's obviously not the way. Also everything works if the observer is triggered some time later after the page load, e.g. by user's typing. This shows that the logic works, it's just the timing that is wrong.

What am I missing?

回答1:

The real issue was having the html imports inside my component's <template>. The 'wrong' order of events makes sense as iron-ajax is not even registered at the time when its host calls the 'ready' callback.

I've moved the imports outside <dom-module> and now everything works as expected.