问题
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.
回答1:
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
回答2:
Use the setElement function inside the ctor instead of el object.
回答3:
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
回答4:
Try setting your el to "#Menu"
module Views {
export class MenuView extends Backbone.View {
constructor(viewOptions?: Backbone.ViewOptions) {
super(viewOptions);
}
el = "#Menu";
回答5:
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");
}
}
}
回答6:
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 ' );
}
}
来源:https://stackoverflow.com/questions/14896087/typescript-backbone-view-events-do-not-fire