Backbone.js 在Typescript中运行BackboneJs事件

Backbone.js 在Typescript中运行BackboneJs事件,backbone.js,typescript,Backbone.js,Typescript,我正在用Typescript编写一个主干程序,在这个程序中我无法初始化任何事件。这里是我创建的一个测试类,用于解决这个问题。单击div时,没有调用函数start() class TestView extends Backbone.View{ events = { "click #testDiv" : "start" } start(){ console.log("Clicked"); } constructor(opt

我正在用Typescript编写一个主干程序,在这个程序中我无法初始化任何事件。这里是我创建的一个测试类,用于解决这个问题。单击div时,没有调用函数
start()

class TestView extends Backbone.View{

    events = {
        "click #testDiv" : "start"
    }

    start(){
        console.log("Clicked");
    }

    constructor(options?){
        super(options);
    }

    render(){
        $root.html(getNewDiv("testDiv"));
        $("#testDiv").css("height", 100).css("width", 100).css("background-color", "green");
        console.log("Rendered");
        return this;
    }
}

function getNewDiv(id:string) {
    return "<div id = \"" + id + "\"></div>"
}

new TestView().render();

下面是我正在使用的主干类型脚本定义:


这是backboneJS的CDN位置

缩小:

非小型化:

我担心我的语法是否正确,或者这与主干的Typescript定义有关

更新

下面Kevin Peel给出的答案是抛出一个错误,因为在Typescript定义文件中,“events”被定义为一个函数(例如events())。如果我只是创建一个“events”函数,我会得到一个错误——“uncaughttypeerror:Object[Object Object]没有“off”方法”。如果我使用getter方法(例如get events(){}),那么在实际触发事件时不会发生任何事情

Using delegate Events
我试图在Backbone.View中使用
delegateEvents()
函数,该函数创建了一个错误:

constructor(options:any, question:Question, div:JQuery) {
        this.delegateEvents({
           "click" : "clicked"
        });
    }
错误:

Uncaught TypeError: Object [object Object] has no method 'off' backbone.js:1082
h.extend.undelegateEvents backbone.js:1082
h.extend.delegateEvents backbone.js:1059

问题在于TypeScript定义事件的位置。当您定义这样的事件时:

class TestView extends Backbone.View {
    events = {
        "click #testDiv": "start"
    }
    // ...
}
 class TestView extends Backbone.View {
   @component({
     events: {
       "click #testDiv" : "start"
     }
   })
   preinitialize(){}

   start(){
     console.log("Clicked");
   }
   render(){
     // ...
   }
 }
TypeScript所做的是在初始化实例后将
事件
附加为属性。因此,当主干网初始化视图时,
事件
尚未连接,因此主干网无法绑定它们

不幸的是,似乎没有一种很好的方法让TypeScript将
事件分配给原型,因此您需要以某种方式绕过它

最简单的方法是自己在原型上设置事件:

class TestView extends Backbone.View {
    // Get rid of the events declaration in here
    // ...
}

TestView.prototype.events = {
    "click #testDiv": "start"
}
解决此问题的第二种可能方法是使用中建议的TypeScript的
getter
功能

最后,第三种方法是在每次渲染时绑定事件。这是解决TypeScript问题的另一种简单方法,但如果视图多次渲染,这可能不是最佳解决方案

class TestView extends Backbone.View{
    events = {
        "click #testDiv" : "start"
    }

    // ...

    render(){
        $root.html(getNewDiv("testDiv"));
        // Here is where you'll bind the events using Backbone's delegateEvents
        this.delegateEvents();
        $("#testDiv").css("height", 100).css("width", 100).css("background-color", "green");
        console.log("Rendered");
        return this;
    }
}

// ...

new TestView().render();

我知道这是一个老问题,但现在有另一种可能性,使用es7装饰器,类似于angular2所做的:

 @component({
   events: {
     "click #testDiv" : "start"
   }
 })
 class TestView extends Backbone.View{
   start(){
     console.log("Clicked");
   }
   render(){
     // ...
   }
 }
装饰文件

export function component(definition: any) {
  return function (constructor: any) {
    Object.assign(constructor.prototype, definition)
  }
}
export function component(definition: any) {
  return function (target: Object, methodName: string, descriptor: TypedPropertyDescriptor<Function>) {
    Object.assign(target, definition)
  }
}
这样,组件装饰器中定义的所有属性都将附加到类原型,并在实例化时可用


除了使用类/构造函数修饰符之外,另一个选项是在
preinitialize
方法上使用方法修饰符,如果您希望将所有代码都放在类括号内,如下所示:

class TestView extends Backbone.View {
    events = {
        "click #testDiv": "start"
    }
    // ...
}
 class TestView extends Backbone.View {
   @component({
     events: {
       "click #testDiv" : "start"
     }
   })
   preinitialize(){}

   start(){
     console.log("Clicked");
   }
   render(){
     // ...
   }
 }
装饰文件

export function component(definition: any) {
  return function (constructor: any) {
    Object.assign(constructor.prototype, definition)
  }
}
export function component(definition: any) {
  return function (target: Object, methodName: string, descriptor: TypedPropertyDescriptor<Function>) {
    Object.assign(target, definition)
  }
}
导出功能组件(定义:任意){
返回函数(目标:对象,方法名:字符串,描述符:TypedPropertyDescriptor){
Object.assign(目标、定义)
}
}

@JqueryLearner我不知道你的意思。这段代码是用Typescript编写的。您熟悉Typescript吗?@JqueryLearner请尝试以下方法:。请不要将评论部分用于与所述问题无关的评论。谢谢。实例化视图时是否存在#testDiv?我不确定getNewDiv是什么或做什么…@KevinPeel谢谢你指出这一点。getNewDiv生成具有指定id的新div html。请查看更新的代码。
$root
是否与
$el
相同?因为为了触发click事件,
#testDiv
必须是视图
el
的后代,而视图
el
不应该有什么区别,因为主干将事件绑定到根
el
,而不是实际元素。看一看,这是一个打字问题。重写答案以解决实际问题。在初始化函数中委派事件如何?不幸的是,在调用
initialize
时,它们还不存在。TypeScript在调用其类的父构造函数之前不会设置
events
属性。在本例中,该构造函数是主干。调用
initialize
(和
delegateEvents
)的视图。理解,尽管您最初建议在呈现方法中委派事件的方法应该有效。。。