Backbone.js 主干网双重过帐问题
我有一个奇怪的主干问题,可能与主干的工作方式有关,我还不明白 我有一个带有按钮的主屏幕,可以转到其他路线。如果我点击一个,然后走那条路线,一切都很好。如果返回菜单并单击同一路线,则每个单击事件都会运行两次。如果我再次这样做,则每次单击事件都会运行三次。。。。等等等等 为什么会发生这种情况?我错过了什么 菜单页面链接:Backbone.js 主干网双重过帐问题,backbone.js,Backbone.js,我有一个奇怪的主干问题,可能与主干的工作方式有关,我还不明白 我有一个带有按钮的主屏幕,可以转到其他路线。如果我点击一个,然后走那条路线,一切都很好。如果返回菜单并单击同一路线,则每个单击事件都会运行两次。如果我再次这样做,则每次单击事件都会运行三次。。。。等等等等 为什么会发生这种情况?我错过了什么 菜单页面链接: <a class="btn btn-large homebutton" id="addcrateslink" data-href="/#/crateadd">Add C
<a class="btn btn-large homebutton" id="addcrateslink" data-href="/#/crateadd">Add Crates To New Location</a>
路由器如何处理该路由:
addcrate: function (eventname) {
var self = this;
this.showLoading();
$("#contentitems").html(" ");
this.ensureLogin(function(){
if (self.crateCollection.length > 0 && self.crateCollection !== null)
{
var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
addCrateView.on('render', self.hideLoading());
}
else
{
//Set Up Sort
self.fetchCrates(function (){
console.log("in the fetchcratescallback");
var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
addCrateView.on('render', self.hideLoading());
});
}
});
},
var AddCrateView = Backbone.View.extend({
template: _.template(AddCrateTemplate),
el: "#contentitems",
utils: new Utils(),
model: new CrateCollection(),
initialize: function (models) {
this.location = models.thelocation;
if (this.location === null || typeof this.location === "undefined")
{
this.location = this.utils.readCookie("location");
}
this.destination = this.utils.readCookie("destination");
this.eventtype = models.eventtype;
this.crate = models.thecrate;
this.crateCollection = models.model;
this.unusedCrates = models.unused;
this.locationCollection = new LocationCollection();
var me = this;
this.locationCollection.fetch({
success: function () {
me.render();
me.on("render", me.utils.showHideContent());
},
error: function () {
me.utils.sendAlert("Uh-Oh!", "There was an error loading this page. Please hit refresh (F5 or CTRL-R).", "error", function(){});
},
});
},
events: {
"click #addnewcrate": "createCrate",
"click #clearlocation": "clearlocation",
"click #cleardestination": "cleardestination",
"click #cratelocationscanlink": "locationscan",
"click #cratescanlink": "cratescan",
"click #cratedestinationscanlink": "destinationscan",
},
showLoading: function () {
...
},
hideLoading: function () {
...
},
createCrate: function (eventname) {
...
},
validateForm: function (currentCrate, unusedCrate) {
...
},
render: function () {
var self = this;
$(this.el).html(this.template({url: this.utils.getDomain() }));
var typeaheadLocation = new TypeaheadLocation({ collection: this.locationCollection, key: 'Name' });
typeaheadLocation.setElement('#locationtaholder').render();
var typeaheadDestination = new TypeaheadDestination({ collection: this.locationCollection, key: 'Name' });
typeaheadDestination.setElement('#destinationtaholder').render();
if (typeof this.location !== "undefined" && this.location !== "") {
var setLocation = this.locationCollection.findWhere({ Name: this.location });
if (typeof setLocation !== 'undefined') {
$("#cratescanfalselink").addClass("item-hidden");
$("#cratescanlink").removeClass("item-hidden");
$('#location').val(setLocation.get("Name"));
$('#clearlocation').removeClass("item-hidden");
if (typeof this.crate !== "undefined") {
// Send the crate to the DB
$('#name').val(this.crate);
self.createCrate();
}
}
else
{
self.utils.sendAlert("Location Error!", "Error setting location: It appears that this location does not exist in the system.", "error", function(){});
}
}
// Set destination
if (typeof self.destination !== "undefined" && self.destination !== "") {
var setDestination = self.locationCollection.findWhere({ Name: self.destination });
if (typeof setDestination !== 'undefined') {
$('#destination').val(setDestination.get("Name"));
$('#cleardestination').removeClass("item-hidden");
}
else
{
console.log("In wrong destination catch...");
self.utils.sendAlert("Location Error!", "Error setting destination: It appears that this destination does not exist in the system.", "error", function(){});
}
}
this.testtype();
},
showRemainingCrates: function(currentLocation, newlocation){
...
},
clearlocation: function () {
...
},
cleardestination: function () {
...
},
testtype: function() {
...
},
locationscan: function (e) {
...
},
destinationscan: function (e) {
...
},
cratescan: function (e) {
...
}
});
在该路线上加载的视图:
addcrate: function (eventname) {
var self = this;
this.showLoading();
$("#contentitems").html(" ");
this.ensureLogin(function(){
if (self.crateCollection.length > 0 && self.crateCollection !== null)
{
var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
addCrateView.on('render', self.hideLoading());
}
else
{
//Set Up Sort
self.fetchCrates(function (){
console.log("in the fetchcratescallback");
var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
addCrateView.on('render', self.hideLoading());
});
}
});
},
var AddCrateView = Backbone.View.extend({
template: _.template(AddCrateTemplate),
el: "#contentitems",
utils: new Utils(),
model: new CrateCollection(),
initialize: function (models) {
this.location = models.thelocation;
if (this.location === null || typeof this.location === "undefined")
{
this.location = this.utils.readCookie("location");
}
this.destination = this.utils.readCookie("destination");
this.eventtype = models.eventtype;
this.crate = models.thecrate;
this.crateCollection = models.model;
this.unusedCrates = models.unused;
this.locationCollection = new LocationCollection();
var me = this;
this.locationCollection.fetch({
success: function () {
me.render();
me.on("render", me.utils.showHideContent());
},
error: function () {
me.utils.sendAlert("Uh-Oh!", "There was an error loading this page. Please hit refresh (F5 or CTRL-R).", "error", function(){});
},
});
},
events: {
"click #addnewcrate": "createCrate",
"click #clearlocation": "clearlocation",
"click #cleardestination": "cleardestination",
"click #cratelocationscanlink": "locationscan",
"click #cratescanlink": "cratescan",
"click #cratedestinationscanlink": "destinationscan",
},
showLoading: function () {
...
},
hideLoading: function () {
...
},
createCrate: function (eventname) {
...
},
validateForm: function (currentCrate, unusedCrate) {
...
},
render: function () {
var self = this;
$(this.el).html(this.template({url: this.utils.getDomain() }));
var typeaheadLocation = new TypeaheadLocation({ collection: this.locationCollection, key: 'Name' });
typeaheadLocation.setElement('#locationtaholder').render();
var typeaheadDestination = new TypeaheadDestination({ collection: this.locationCollection, key: 'Name' });
typeaheadDestination.setElement('#destinationtaholder').render();
if (typeof this.location !== "undefined" && this.location !== "") {
var setLocation = this.locationCollection.findWhere({ Name: this.location });
if (typeof setLocation !== 'undefined') {
$("#cratescanfalselink").addClass("item-hidden");
$("#cratescanlink").removeClass("item-hidden");
$('#location').val(setLocation.get("Name"));
$('#clearlocation').removeClass("item-hidden");
if (typeof this.crate !== "undefined") {
// Send the crate to the DB
$('#name').val(this.crate);
self.createCrate();
}
}
else
{
self.utils.sendAlert("Location Error!", "Error setting location: It appears that this location does not exist in the system.", "error", function(){});
}
}
// Set destination
if (typeof self.destination !== "undefined" && self.destination !== "") {
var setDestination = self.locationCollection.findWhere({ Name: self.destination });
if (typeof setDestination !== 'undefined') {
$('#destination').val(setDestination.get("Name"));
$('#cleardestination').removeClass("item-hidden");
}
else
{
console.log("In wrong destination catch...");
self.utils.sendAlert("Location Error!", "Error setting destination: It appears that this destination does not exist in the system.", "error", function(){});
}
}
this.testtype();
},
showRemainingCrates: function(currentLocation, newlocation){
...
},
clearlocation: function () {
...
},
cleardestination: function () {
...
},
testtype: function() {
...
},
locationscan: function (e) {
...
},
destinationscan: function (e) {
...
},
cratescan: function (e) {
...
}
});
听起来你可能有僵尸视图问题。您的旧观点可能不会被清理 一种策略是在路由器中创建一个变量来保存对当前视图的引用。在加载另一个视图之前,请检查该变量是否包含视图,如果包含,请在添加新视图之前查看该变量 这将从DOM中完全删除它,并解除其中任何事件的绑定
if (currentView && 'remove' in currentView) {
currentView.remove();
}
在发布相关脚本后,我最好的心理猜测是,您渲染的视图模板不正确。:-)很好。(我只是觉得这是我完全错过的东西)我已经添加了代码…只是猜测一下…在后续请求相同视图时再次创建视图之前,您是否尝试调用视图的remove()方法?这将解除所有事件侦听器的绑定。@NathanHarkenrider:他需要重写
remove
,以将This.$el.remove()
替换为This.$el.empty()
和This.undelegateEvents()
。好的。因此,当我处理完视图后,我需要删除并取消绑定它们。我似乎无法在我的路由器中访问它们。。。。例如,如果(this.addCrateView)在路由器的addcratet函数中返回false。不用担心……我刚刚创建了一个主路由器视图,将该视图加载到其中,因此每次加载新视图时都可以访问它。谢谢