A
A
Al2016-11-06 02:24:18
JavaScript
Al, 2016-11-06 02:24:18

Why is this not available in callback?

I am making a class for pagination, using a wrapper for jquery inside it - the Request class . The getRecords method is a callback that is hung on $(window).scroll() , internally it calls the Request class to make a request, inside of which onRequest is a success callback that calls $.ajax( ). Inside onRequest , this no longer contains Pagination, but contains an object containing request data.

export class Pagination{

    constructor (params? :Object){
        //.. more actions
        this.getRecords();
        fn.setOnWindowListener('scroll','pagination',null,(e) => {this.setScrollEvent(e)});
    }

    private setScrollEvent = (e) :void =>{
        let pos = $(e.currentTarget).scrollTop() + this.paginationHeight;
        let height = $(document).height();
        if(pos >= height && !this.doRequest) this.getRecords();
    };

    public getRecords = () :void =>{
        this.doRequest = true;
        //здесь this - ссылка на Pagination
        return new Request({
            url: this.url + this.currentPage,
            type: `GET`,
            dataType: this.requestDataType,
            onRequest: (data) =>{
                //а здесь this превратился в объект $.ajax()
                this.doRequest = false;
                this.currentPage++;
                this.onRecordsLoaded(data);
            }
        }).exec();
    };

}

The question is how to pass this from Pagination to onRequest so that Pagination properties are available inside onRequest ? ps of course you can create a variable like var _self = this before new Request() ; and further already in onRequest to pull it, but this will already be a crutch pulling approach used in es5. This is not an option, because I want to make everything beautiful. pps So far I've made the context transfer in this way, passing this to getRecords,

public getRecords = (context: Pagination) :void =>{
        context.doRequest = true;
        return new Request({
            url: context.url + context.currentPage,
            type: `GET`,
            dataType: context.requestDataType,
            onRequest: (data) =>{
                context.doRequest = false;
                context.currentPage++;
                context.onRecordsLoaded(context.context, data);
            }
        }).exec();
    };

And in the constructor, in the same way, remember the context of the class from which the Pagination instance was created :
constructor (context :Object, params? :Object){
        this.context = context;

Answer the question

In order to leave comments, you need to log in

4 answer(s)
R
Ruslan Lopatin, 2016-11-06
@lorus

The error is in Request. There, apparently, onRequest is passed to $.ajax directly, something like this:

$.ajax({
  url: this.url + this.currentPage,
  type: `GET`,
  /*... more params */
}).done(this.onRequest);

Naturally, $.ajax overwrites this.
You need something like this:
$.ajax({
  url: this.url + this.currentPage,
  type: `GET`,
  /*... more params */
}).done(data => this.onRequest(data))

B
Bowen, 2016-11-06
@Bowen

Try to put the Request in a separate method, for example:

public ajax = (params) => new Request(params);
this.ajax({
           url: this.url + this.currentPage,
            type: `GET`,
            dataType: this.requestDataType,
            onRequest: (data) =>{
                //а здесь this превратился в объект $.ajax()
                this.doRequest = false;
                this.currentPage++;
                this.onRecordsLoaded(data);
            }
})

E
Eugene, 2016-11-06
@Methos

Use .bind(this)

A
Artem Kayun, 2016-12-01
@Kayun

In your example #onRequest is called in the context of $.ajax and the arrow function won't help here. In general, look at the implementation of Request

private _requestSuccess(data) =>{
        this.doRequest = false;
        this.currentPage++;
        this.onRecordsLoaded(data);
}

public getRecords = () :void =>{
        this.doRequest = true;
        //здесь this - ссылка на Pagination
        return new Request({
            url: this.url + this.currentPage,
            type: `GET`,
            dataType: this.requestDataType,
            onRequest: this._requestSuccess.bind(this)
        }).exec();
    };

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question