【问题标题】:Access TypeScript functions from JavaScript从 JavaScript 访问 TypeScript 函数
【发布时间】:2013-08-15 05:09:33
【问题描述】:

我想将 TypeScript 与 jsTree 一起使用。如何在绑定的jsTree函数中调用setCurrentNode函数?

class MyController {
    thescope: any;
    static $inject = ['$scope'];

    constructor($scope) {
        $scope.vm = this;
        this.thescope = $scope;

        (<any>$("#demo2")).jstree({
             .bind("select_node.jstree", function (e, data) {
              // how can I call setCurrentNode(data) here?
             }
        });

    }


    setCurrentNode(node: any): any {
        ... // do Stuff in this typescript function
    }
}

【问题讨论】:

  • .bind("select_node.jstree", function (e, data) { this.setCurrentNode(data); });? function 不会捕获 this,但箭头函数会捕获 this

标签: javascript typescript jstree


【解决方案1】:

解决方案:

(<any>$("#demo2")).jstree({
         .bind("select_node.jstree", this.setCurrentNode.bind(this) )
         }

public setCurrentNode(e:any,data: any): any {
   ...
}

【讨论】:

    【解决方案2】:

    我不完全确定,如果我错了,请纠正我,但是使用lamba表达式不也能解决这个问题吗?

    如下:

    class MyController {
        thescope: any;
        static $inject = ['$scope'];
    
        constructor($scope) {
            $scope.vm = this;
            this.thescope = $scope;
    
            (<any>$("#demo2")).jstree({
                 .bind("select_node.jstree", (e, data) => {
                     this.setCurrentNode(e, data);
                 }
            });
    
        }
    
        setCurrentNode(e: any, node: any): any {
            ... // do Stuff in this typescript function
        }
    }
    

    lambda (=&gt;) 表达式将确保函数在与您定义它的范围相同的范围内执行。如果您查看已编译的 JavaScript 代码,您会发现他将保留一个引用构造函数作用域并将在该作用域上调用setCurrentNode。简化示例:

    var _this = this;
    $("#demo2").jstree({
         .bind("select_node.jstree", (e, data) => {
             _this.setCurrentNode(e, data);
         });
    

    我相信这会解决您的问题?

    附带说明,您应该查找 jsTree 定义文件或至少自己添加一个存根声明,这样您就不需要将 JQuery 强制转换为任何文件。只是我的 2cts,我觉得很难看。

    【讨论】:

      【解决方案3】:

      根据 Anzeo 的建议,为了避免将 $ 转换为以下任何内容,您只需开始:

      interface JQuery{
              jstree:Function;
      }
      

      【讨论】:

        【解决方案4】:

        它发生的是内部 jsTree 回调正在覆盖对实例对象的 this 初始引用。

        有两种安全的方法可以解决这个问题:

        1- 通过使用@Anzeo 所指的箭头函数,我不推荐也从不使用它,因为如果您需要另一个嵌套回调,那么您可以使用 this引用最里面的事件对象。

        2- 通过缓存 this 对实例对象的引用,例如:

        class MyController {
            thescope: any;
            static $inject = ['$scope'];
        
            constructor($scope) {
                // Caching the reference for using it in the inner callbacks.
                var self = this;
        
                $scope.vm = this;
                this.thescope = $scope;
        
                (<any>$("#demo2")).jstree({
                     .bind("select_node.jstree", function (e, data) {
        
                      // Call to the instance method here!
                      self.setCurrentNode(/*Node params here*/);
                     }
                });
        
            }
        
        
            setCurrentNode(node: any): any {
                ... // do Stuff in this typescript function
            }
        }
        

        我建议您坚持使用 2,因为它适用于任何嵌套级别,并且您可以让每个嵌套回调中的 this 指向正确的事件对象。

        更多参考请参见Javascript 'this' overwriting in Z combinator and every other recursive function,因为问题与此处相同。

        【讨论】:

        • 我不明白您对 lambda(箭头)函数的反对意见?您是继续使用 lambda 函数在每个嵌套函数中获取对原始范围的引用,还是不保留嵌套函数的范围?因为您的第二种方法是不必要的,因为 lambda 表达式会为您执行此操作(如果您查看已编译的 JavaScript 输出)。
        • 是的,它会为您执行此操作,但会在每个嵌套级别覆盖 this 引用,这使得在内部回调中引用当前对象(不是类实例!)不可能(如果您发现没有this缓存的方法请告诉我!)。有关更多参考,请参阅this excellent discussion。如果您愿意,我们可以将此讨论转移到聊天中,以便我们进一步讨论,也许您可​​以指出它的正确用法,但我认为 TypeScript 必须编写一个保留字,如 self 始终指向 Class 实例。
        猜你喜欢
        • 2015-12-18
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-06
        • 2015-03-06
        • 1970-01-01
        相关资源
        最近更新 更多