2
votes

I'm trying to make a simple view to test with backbone. I've started with events, but no one fires. Why ? I've made already other things with backbone like routing etc. without problems. Thanks for your time. My backbone definitions are from -> this source <-

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

        super(viewOptions);
    }

    el = document.body;
    events = {
        "click #Btn-Start": "navigate",
        "click #Btn-Software": "navigate",
        "click #Btn-Anderes": "navigate",
        "click #Btn-Impressum": "navigate"
    };

    initialize() {
        console.log("initialize"); // fire
    }

    render() {
        console.log("render"); // not fire
    }

    navigate() {
        console.log("navigate"); // not fire
    }
}

}

<body>
    <div id="Menu">
        <div id="Btn-Start"></div>
        <div id="Btn-Software"></div>
        <div id="Btn-Anderes"></div>
        <div id="Btn-Impressum"></div>
    </div>
<body>

EDIT: Tried routes with the route(name: string, callback: function) and the routes as object. It seems to work with a function reference but not as string in the routes object. Maybe there is a way to declare it in the view like these.

6
Where and when do you instantiate your MenuView? Because you should do it when the DOM is loaded...nemesv
@nemesv document.readyMR.ABC
Have you referenced jquery? And you can try with el = "body". And also the typescirpt MenuView extends Backbone.View is not exactly the same with the Backbone way: var MenuView = Backbone.View.extend({ ...nemesv
@nemesv yeep jquery is referenced.. $el = $("body") doesn't work etherMR.ABC
did anybody tried the events of the views with backbone and typescript ?MR.ABC

6 Answers

2
votes

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

1
votes

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

1
votes

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

0
votes

Try setting your el to "#Menu"

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

        super(viewOptions);
    }

    el = "#Menu";
0
votes

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");
       }
    }
}
0
votes

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 ' );    
   }
}