首页 > 解决方案 > 无法使用“this”指针将方法用作回调

问题描述

好的,所以在我的程序中,我必须提供一个回调作为事件侦听器作为init()我的类方法的一部分,并且我希望这个回调是同一个类的另一个方法(onPageShown(ev)来自下面的代码)。

const pageShownEvent = new Event("pageShown");

class App
{

    private pages: NodeListOf<HTMLDivElement>;

    public onPageShown(ev: Event) {
        console.log("Method called as callback");
    }

  
    public init() {
        this.pages = <NodeListOf<HTMLDivElement>> document.querySelectorAll(".page");
        console.log(this.pages);

        for(let i = 0; i < this.pages.length; ++i) 
        {
            this.pages[i].addEventListener("pageShown", this.onPageShown);
        }

        /*this.pages.forEach((pg: HTMLDivElement) => {
            pg.addEventListener("pageShown", this.onPageShown);
            
        });*/
        
    }

    // singleton instance
    private static instance: App;

    private constructor() {
        this.pages = null
    }

    // ensure only 1 instance is created
    public static getInstance() {
        if(!App.instance) {
            App.instance = new App()
        }
        
        return App.instance;
    }

}

const myApp = App.getInstance();

但是,问题是每当我使用this指针访问onPageShow时,它似乎都没有被添加或解释为回调函数。没有抛出错误,自动完成仍然按预期工作,暗示this仍然指向正确的对象。

this.pages[i].addEventListener("pageShown", this.onPageShown);

我让它工作的唯一方法是onPageShown通过(它的一个单例类)给出的类实例显式提供getInstance(),在这种情况下它工作得很好,我在控制台中看到了正确的输出。

this.pages[i].addEventListener("pageShown", App.getInstance().onPageShown);

起初,我认为this在使用实现的回调时指向了错误的对象forEach(),但即使在我切换到使用常规 for 循环之后,问题仍然存在。

似乎我当前的解决方案也可以正常工作,但它需要我设置我想用作公共回调的方法,而我更希望它们是私有的this访问私有成员应该没问题,如果它不是?)。

如果有人能够提供一些智慧,将不胜感激。

编辑:我错了,似乎获得指向当前对象的指针的两种方式都允许我调用私有函数,只要它在所述对象内完成。但是,我仍然不知道为什么在我的两个代码片段中,一个有效而一个无效。

编辑2:编译的JS代码抛出错误“未捕获的TypeError:this.onPageShown不是HTMLDocument.App.init的函数”

var pageShownEvent = new Event("pageShown");
var App = /** @class */ (function () {
    function App() {
        this.pages = null;
    }
    App.prototype.onPageShown = function (ev) {
        console.log("Method called as callback");
    };
    App.prototype.navToPage = function (pageId) {
        console.log("Nav to page " + pageId);
        document.querySelector(".active").classList.remove("active");
        document.getElementById(pageId).classList.add("active");
        document.getElementById(pageId).dispatchEvent(pageShownEvent);
    };
    App.prototype.init = function () {
        this.pages = document.querySelectorAll(".page");
        console.log(this.pages);
        for (var i = 0; i < this.pages.length; ++i) {
            this.pages[i].addEventListener("pageShown", App.getInstance().onPageShown);
            /*
               TypeError thrown here
            */
            this.onPageShown(null); 
        }
        /*this.pages.forEach((pg: HTMLDivElement) => {
            pg.addEventListener("pageShown", App.getInstance().onPageShown);
            
        });*/
        document.querySelectorAll(".nav-link").forEach(function (link) {
            link.addEventListener("click", function (ev) {
                //console.log("click");
                ev.preventDefault;
                var target = ev.target;
                var currentPage = target.getAttribute("data-target");
                console.log(currentPage);
                App.getInstance().navToPage(currentPage);
                /*document.querySelector(".active").classList.remove("active");
                document.getElementById(currentPage).classList.add("active");

                document.getElementById(currentPage).dispatchEvent(pageShownEvent);*/
                //history.replaceState({}, currentPage, `#${currentPage}`);
            });
        });
        //history.replaceState({}, "1", "#1");
    };
    // ensure only 1 instance is created
    App.getInstance = function () {
        if (!App.instance) {
            App.instance = new App();
        }
        return App.instance;
    };
    return App;
}());

标签: typescript

解决方案


推荐阅读