简体   繁体   中英

Accessing Vue methods from anonymous function

I'm just having a play with Vue.js (pretty new to javascript too) and trying to access the events in my Google calendar.

I keep getting 'undefined' when looking in the console.

    new Vue({
    el: '#app',
    data: {
        client_id: 'my_client_id',
        scopes: ["https://www.googleapis.com/auth/calendar.readonly"],
        events: {
            title: 'Upcoming Events',
            items: [],
        }
    },
    created: function () {
        this.loadCalendarApi();
    },
    methods: {
        addEvent: function (event) {
            this.events.items.push({
                title: event.summary,
                date: event.start.dateTime
            });
        },
        loadCalendarApi: function () {
            gapi.client.load('calendar', 'v3', this.listUpcomingEvents);
        },
        listUpcomingEvents: function () {
            var request = gapi.client.calendar.events.list({
                'calendarId': 'primary',
                'timeMin': (new Date()).toISOString(),
                'showDeleted': false,
                'singleEvents': true,
                'maxResults': 10,
                'orderBy': 'startTime'
            });
            var events = this.requestEvents(request);
            console.log(events);
        },
        requestEvents: function (request) {
            return request.execute(function (resp) {
                resp.items;
            });
        },
    },
});

I think the offending code is somewhere in the requestEvents method.

I also know that 'this.addEvent' is not in scope to be able to refer to the Vue object from inside the request.execute function but I don't know what I need to change.

Can anyone help me or let me know what I'm doing wrong?

Thanks!

Two ways you could do it, one would be to change execute(function) to execute(function, vue) and pass this in as the second argument. Then you could access it like so:

//update your execute function to pass along the vue variable into the response, then

requestEvents: function (request) {
        var events = request.execute(function (resp, vue) {
            for (i = 0; i < resp.items.length; i++) {
                vue.addEvent(resp.items[i]);
            }
        }, this);
        return events;
    }

Or if you have jQuery available, you can take a look at $.proxy() which alters a function to use the current context: https://api.jquery.com/jQuery.proxy/

requestEvents: function (request) {
        var events = request.execute($.proxy(function (resp) {
            for (i = 0; i < resp.items.length; i++) {
                this.addEvent(resp.items[i]);
            }
        }, this));
        return events;
    }

This way the anonymous response function will be run in the context of your Vue object.

Edit: I found this page as well which shows how you can bind the current context to a function using native JS, jQuery, or Underscore. Any of these would work: https://jsperf.com/bind-vs-jquery-proxy/5

Nowadays you could use the request => {} notation instead of function(request) {} notation, which will pass on the context to the executing method so this.AddEvent() will work as expected.

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