backbone-view-Ereignisse funktionieren nicht nach neu Rendern
Ich bin mein Haar ziehen, ich kann nicht scheinen, um Mausereignisse zu arbeiten, auf mein Rückgrat Ansicht nach die view neu gerendert, es sei denn, ich mache das lächerlichste was:
$("a").die().unbind().live("mousedown",this.switchtabs);
Eigentlich hatte ich diese, aber beschlossen, zu aktualisieren, um die neuesten Rückgrat und versuchen, die neue delegateEvents()
Funktion.
Hier ist übrigens meine Projekt-id strukturiert:
Appview / AppRouter
|
----->PageCollection
|
------->PageView/PageModel
------->PageView/PageModel these page view/models are not rendered
------->PageView/PageModel
|
------->PageView/PageModel
|
----->render() *when a pageview is rendered*
|
-----> Creates new
Tabcollection
|
--->TabModel/TabView <-- this is where the issue is
Was passiert, ist, dass die tabcollection verfügt über ein Haupt-tabview zu verwalten alle Register, erstellt dann ein neues model/view für die einzelnen Register und legt einen listener neu Rendern die tabview, wenn ein tab geladen wird. Wenn die tabview ist neu gerendert, es werden keine Mausereignisse mehr funktionieren, es sei denn, ich setzte den künstlich jQuery-Anweisung drin.
Heres die tabview und render (ive beraubt es unten ganz ein bisschen)
var TabPanelView = Backbone.View.extend({
className: "tabpanel",
html: 'no content',
model: null,
rendered: false,
events:{
'click a.tab-nav': 'switchtabs'
},
initialize: function(args)
{
this.nav = $("<ol/>");
this.views = args.items;
this.className = args.classname?args.classname:"tabpanel";
this.id = args.id;
this.container = $("<section>").attr("class",this.className).attr("id",this.id);
_.bindAll(this);
return this.el
},
/*
This render happens multiple times, the first time it just puts an empty html structure in place
waiting for each of the sub models/views to load in (one per tab)
*/
render: function(args){
if(!args)
{
//first render
var nav = $("<aside/>").addClass("tab-navigation").append("<ol/>").attr("role","navigation");
var tabcontent = $("<section/>").addClass("tab-panels");
for(i = 0;i<this.views.length;i++)
{
$("ol",nav).append("<li><a rel='"+this.views[i].id+"' href='javascript:;' class='tab-nav'></a></li>");
tabcontent.append(this.views[i].el);
}
this.$el.empty().append(nav).append(tabcontent);
}
else if(args && args.update == true){
//partial render -- i.e. update happened inside of child objects
var targetid = args.what.cid;
for(i = 0;i<this.views.length;i++)
{
var curcontent = this.$el.find("div#"+this.views[i].id);
var curlink = this.$el.find("a[rel='"+this.views[i].id+"']")
if(this.views[i].cid == targetid)
{
curcontent.html($(this.views[i].el).html());
curlink.text(this.views[i].model.rawdata.header);
}
if(i>0)
{
//set the first panel
curcontent.addClass("tab-content-hide");
}
if(i==0)
{
curcontent.addClass("tab-content-show");
curlink.addClass("tab-nav-selected");
}
//this ridiculous piece of jQuery is the *ONLY* this i've found that works
//$("a[rel='"+this.views[i].id+"']").die().unbind().live("mousedown",this.switchtabs);
}
}
this.delegateEvents();
return this;
},
switchtabs: function(args){
var tabTarget = args.target?args.target:false
if(tabTarget)
{
this.$el.find("aside.tab-navigation a").each(function(a,b)
{
$(this).removeClass("tab-nav-selected")
})
$(tabTarget).addClass("tab-nav-selected");
this.$el.find("div.tab-content-show").removeClass("tab-content-show").addClass("tab-content-hide");
this.$el.find("div#"+tabTarget.rel).removeClass("tab-content-hide").addClass("tab-content-show");
}
}
});
Kann sich jemand denken, warum backbone-Maus-events, die einfach nicht das Feuer überhaupt, ist es, weil Sie nicht auf dem DOM? Ich dachte, dass dies war, wo Rückgrat war besonders nützlich?...
- Welche Schritte haben Sie unternommen, um dies zu beheben, so weit? Ein paar Dinge, die ich versuchen würde: Sehen Sie, wenn Sie können, legen Sie einen Haltepunkt in das Rückgrat Quelle, wo die
events
element verarbeitet. Vielleicht geben Sie einen kleinen Einblick. Auch, versuchen Sie es mit Chrome DOM-und Event Listener breakpoints. Dies kann Ihnen helfen, zu überprüfen, wenn irgendein code ausgeführt wird, oder wenn die Ereignisse nur nicht zu verdrahten. - Ive angemeldet gegen jq $(document).finden("tab-nav-selected"), um zu sehen, wenn die erstellten Gegenstände sind eigentlich auf dem dom.. fein die richtigen Ergebnisse. gegangen durch die Haltepunkte, in meinem eigenen code. Ich bin nicht selbstbewusst genug, mit ihm zu gehen Graben im backbone selbst mit dem debugger. der Umfang scheint alles in Ordnung... ich bin nicht sicher, mit allen Mitteln, aber es scheint, als ob die Ereignisse sind entweder überschrieben werden, aufgrund der re-rendering oder ähmm...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese Zeile von code ist wahrscheinlich dein problem:
this.delegateEvents();
Entfernen und es sollte funktionieren.
Die einzige Zeit, die Sie brauchen zu call
delegateEvents
Sie sich, wenn Sie Ereignisse, die deklariert sind, getrennt von Ihrer Ansichtevents
hash. Backbone-Sicht nennen diese Methode für Sie, wenn Sie erstellen eine Instanz von der Ansicht.Wenn sich das Bild neu gerendert werden, sind Sie der Wiederverwendung der gleichen Ansicht und nur render() aufrufen wieder drauf, oder sind Sie das löschen der anzeigen und erstellen einen ganz neuen Blick?
So oder so, es sieht aus wie die Ursache ist, dass die Ereignisse anzuzeigen, die nicht losgebunden, bevor die view neu gerendert. Derick Bailey hat eine große post über diese.
Wenn Sie re-Rendern, 1) stellen Sie sicher, dass Sie unbind-alle Veranstaltungen in der alten Ansicht und 2) erstellen einer neuen Ansicht und render es
Bei der Verwendung
$(el).empty()
es entfernt alle untergeordneten Elemente des ausgewählten Elements UND entfernt ALLE die Veranstaltungen (und Daten), die gebunden ist, (Kind -) Elemente innerhalb des selektierten Elements (el
).Zu halten die Ereignisse gebunden die Kind-Elemente, aber entfernen Sie noch die Kind-Elemente verwenden:
$(el).children().detach();
statt$(.el).empty();
So können Ihre anzeigen ihn neu zu Rendern erfolgreich mit den Ereignissen, die Sie immer noch gebunden sind und arbeiten.
this.$el.children().detach().append(nav).append(tabcontent);
und es sollte Arbeit perfekt. Keine Notwendigkeit, neu zu erstellen eine Instanz von der Ansicht.