Can't find element on iron ajax event methods

社会主义新天地 提交于 2019-12-13 05:55:51

问题


For below given code this.$.createButton or document.querySelector('createButton') works inside the ready method. But same code fails inside handleRequestSent or handleResponseReceived. The error message I get is

Uncaught TypeError: Cannot read property 'createButton' of undefined

I tried to debug, it appears that inside handleRequestSent and handleResponseReceived the this actually pointing to iron-ajax, but not the element dom root. Any suggestion is welcome. Thanks in advance.

<dom-module id="bortini-tv-create">
    <template>
        <form>
            <paper-input label="Name" value="{{tv.name}}"></paper-input>
            <paper-input label="Logo" value="{{tv.logo}}"></paper-input>
            <paper-input label="Address" value="{{tv.address}}"></paper-input>
            <paper-input label="Web site" value="{{tv.webSite}}"></paper-input>
            <paper-input label="Registration number" value="{{tv.regNumber}}"></paper-input>
            <br/>
            <br/>
            <paper-button id="createButton" raised on-tap="handleTvCreate">
                <iron-icon icon="redeem"></iron-icon>
                Add
            </paper-button>
            <paper-button id="cancelButton" raised on-tap="handleCancelTvCreate">
                <iron-icon icon="cancel"></iron-icon>
                Cancel
            </paper-button>
        </form>

        <iron-ajax
                id="ironAjax"
                url="/api/tv"
                content-type="application/json"
                handle-as="json"
                method="POST">
        </iron-ajax>

        <paper-toast id="toast"
                     duration="3000"
                     text="TV {{tv.name}} has been created">
        </paper-toast>
    </template>
</dom-module>
<script>

    function initModel() {
        return {"name": "", "logo": "", "address": "", "webSite": "", "regNumber": ""};
    }


    Polymer({
        is: "bortini-tv-create",
        properties: {
            tv: {
                type: Object,
                value: initModel(),
                notify: true
            }
        },
        ready: function() {
            this.$.ironAjax.addEventListener('error', this.handleError);
            this.$.ironAjax.addEventListener('request', this.handleRequestSent);
            this.$.ironAjax.addEventListener('response', this.handleResponseReceived);
        },
        handleTvCreate: function (event) {
            var ironAjax=document.querySelector("#ironAjax");
            ironAjax.body = JSON.stringify(this.tv);
            ironAjax.generateRequest();
        },
        handleCancelTvCreate: function (event) {
            MoreRouting.navigateTo('tv-list');
        },
        handleError: function(event) {
            this.$.createButton.disabled=false;
            this.$.cancelButton.disabled=false;

            var request=event.detail.request;
            var error=event.detail.error;
            var toast=document.querySelector("#toast");
            toast.text="Error: "+error;
            toast.show();
        },
        handleRequestSent: function (request) {
            console.log("boooooo");
            this.$.createButton.disabled=true;
            this.$.cancelButton.disabled=true;

        },
        handleResponseReceived: function (response) {
            document.querySelector('createButton').disabled=false;
            document.querySelector('cancelButton').disabled=false;

            console.log("Received response: " + JSON.stringify(response.detail.response));
            document.querySelector('#toast').show();
            MoreRouting.navigateTo('tv-list');
        }
    });
</script>

回答1:


Because you set your event handlers imperatively the scope (i.e this) the handler is called with, isn't your element instance.

Two ways to solve this:

  1. Bind the event handler to your element instance:

    this.$.ironAjax.addEventListener('error', this.handleError.bind(this));

    This will make sure that this inside of the event handler is actually the this you want.

  2. Define the event handlers declaratively, then Polymer will take care of the proper binding:

    <iron-ajax ... on-error="handleError" ...></iron-ajax>




回答2:


this is because the responseHandler method is fired from an iron-request-element inside. So the this-context moves to the iron-ajax element. If you want to return to your "original" firing element from there, simply use the this.parentElement try something like this:

[...]
handleResponseReceived: function( request ) 
{
  var that = this.parentElement;
  that.$.createButton.disabled=true;
}

This should do the trick. Sorry for answering that late. ;)



来源:https://stackoverflow.com/questions/30865384/cant-find-element-on-iron-ajax-event-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!