Typescript Backbone View Events do not fire

孤街醉人 提交于 2019-12-06 15:01:31

There is an issue with initialization sequence between Backbone and typescript constructor. Constructor is generated as

_super.call(this, attributes); this.events = { "click a.back": "back", "click a.changeDate": "changeDate" }; >

but Backbone hooks events (and call initialize) from _super.call

var View = Backbone.View = function(options) {
   this.cid = _.uniqueId('view');
   this._configure(options || {});
   this._ensureElement();
   this.initialize.apply(this, arguments);
   this.delegateEvents();
};

Backbone expects that View object is fully initialized by the time when constructor is called which is not the case.

The best solution I found so far is to use Backbone.extend instead of class

export var MyView = Backbone.View.extend

Issue 1098 in typescript project on codeplex

Use the setElement function inside the ctor instead of el object.

All answers are not correct answers.

you need to use the getter, because this one is set to the prototype, while usual properties are set after the parent ctor is called - that´s too late.

use this for proper functionality

export class View extends Backbone.View {
    get events() { 
        return { 
            "click .button" : "myEvent"
        }
    }
}

the same you have to do for Collection when you are setting the model property. Otherwise Backbone will use the default Backbone.Model Type

Try setting your el to "#Menu"

module Views {
export class MenuView extends Backbone.View {
    constructor(viewOptions?: Backbone.ViewOptions) {

        super(viewOptions);
    }

    el = "#Menu";

Try this. Basically, all the events and any preliminary instantiation/pre-processing goes in the Constructor instead.

The reason why render() and navigate() are not firing is because, the events are not properly hooked up.

module Views {
    export class MenuView extends Backbone.View {
        constructor(viewOptions?: Backbone.ViewOptions) {
            super(viewOptions);

            // Any initialization goes in the constructor.
            this.el = document.body;
            this.events = {
                 "click #Btn-Start": "navigate",
                 "click #Btn-Software": "navigate",
                 "click #Btn-Anderes": "navigate",
                 "click #Btn-Impressum": "navigate"
            };

            // Precompile and cache the template.
            this.template = _.template($('#template').html());
            console.log("initialize");
       }
       render() {
            console.log("render");
            return this;
       }
       navigate() {
            console.log("navigate");
       }
    }
}

Try it.

file: requirejsConfig.ts

require.config({
    paths: {
        jquery: 'bower_components/jquery/dist/jquery',
        underscore: 'bower_components/underscore/underscore',
        backbone: 'bower_components/backbone/backbone',
        test: 'test'
    }
});

require(['test'], function(Test: any){
    new Test.test; 
});

file: test.ts

/// <reference path="../typings/tsd.d.ts" />

import Backbone = require('backbone');
import $ = require( 'jquery');


export class Test extends Backbone.View<Backbone.Model> {
   events(): Backbone.EventsHash
    { 
        return { 
            'click': 'showResult'            
        }
    }
    constructor( options?: any )
    {
        super(options);
        this.setElement( $( '.test-el' ), true );        
    }    
   protected showResult(): void 
   {
        console.log( 'show result ' );    
   }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!