2011-08-18 10 views
14

işlemek bir omurga içerisine bir jQuery eklentisi çağrılması: Bir yönlendirici eylemden denirböyle temelde gider omurga içerisine bir hale yöntemine sahip yöntem

render: function() { 
    $.tmpl(this.template, attrs).appendTo(this.el); 
    return this; 
}, 

: Artık

action: function() { 
    $('#container').empty(); 
    $('#container').append(myView.render().el); 
}, 

, ben Bu görünümde label öğelerine bir eklenti uygulamak istiyorum.

render: function() { 
    $.tmpl(this.template, attrs).appendTo(this.el); 
    this.$('label').inFieldLabels(); 
    return this; 
}, 

ama bu (I eleman henüz DOM eklenmemiş çünkü bu olduğunu varsayarak yaşıyorum) çalışmaz: İlk düşüncem render içindeki eklenti aramak oldu.

action: function() { 
    $('#container').empty(); 
    $('#container').append(myView.render().el); 
    myView.$('label').inFieldLabels(); 
}, 

Doğrusu bunu istiyorum eklentisi görüntüsü değil, yönlendirici bir parçası olduğu için yapmaz bu nedenle,: Ama yönlendirici eylem eklentisi diyoruz eğer çalışır eylemin içinde onu aramak anlamında. Bunu yapmanın daha iyi bir yolu var mı?

cevap

0

Görünümümün bir loadPlugins yöntemini ekleyerek bu sorunu çözdüm, bu yüzden eylemi gerçekleştirdikten sonra myView.loadPlugins() yapabilirim. İdeal değil, ama işe yarıyor.


Düzenleme: Eh, heard from the horse's mouth ettik ve ben eleman DOM eklendiğinden önce eklentiyi uygulayamazsınız gibi görünüyor, bu yüzden ya ben (loadPlugins birlikte) yukarıdaki gibi yapabilir ya da ben Kodu değiştirebilir, böylece öğe render yönteminde DOM'a eklenir. Umarım bu, benzer bir pozisyonda birine yardımcı olur. İşte

ben şimdi yapıyorum nasıl:

//in router 
action: function() { 
    var myView = new MyView({ 
    el: '#container' 
    }); 
} 

//in view 
render: function() { 
    $.tmpl(this.template, attrs).appendTo(this.el); //this now appends to the DOM 
    this.loadPlugins(); 
    return this; 
}, 

loadPlugins: function() { 
    this.$('label').inFieldLabels(); 
    //and other plugins 
}, 
5

Beter bunu şu şekilde yapın:

action: function() { 
    var container = $('#container'); 

    container.empty(); 
    myView.render(container); 
}, 

render: function (container) { 
    $(this.el) 
     .append($.tmpl(this.template, attrs)) 
     .appendTo(container); 
    $('label', this.el).inFieldLabels(); 
    return this; 
}, 
+1

Teşekkür: – Skilldrick

+0

teşekkürler! Bilmiyor;) –

0

Hatta yukarıdaki çözümler benzer bir sorunla karşı karşıya ama benim durumumda oldu olmaz iş, ana görünümler henüz DOM'a eklenmemiş olduğundan.

Ebeveyn görünümüne sahip olma kuralına uymak, çocukları DOM'a ekler, render yönteminde loadPlugins() yapmak işe yaramadı.

Yaptığım şey budur. zaman aşımı işlevi alır, böylece bitirmek için geçerli çağrı yığını

render: function() { 
    var self = this; 

    setTimeout(function() { 
    $(self.el).setupPlugin(); 
    }, 0); 

    return this; 
} 

0 bir setTimeout kullanarak sağlar: Bu nasıl hiyerarşisinde görüşlerinizi yönetiyorsanız bağlı hacky tür hissediyor ama yardımcı olabilecek görünümü çağırdı ve tüm ebeveynler DOM'a eklendi. (Yukarıda belirtilen kurala sadık kalırsanız).

+0

Belirli bir öğe DOM'a eklendiğinde ateşleyen bir olay dinleyicisinin eklenmesinin bir yolu olsaydı daha iyi olurdu. Bunu yapmanın bir yolu bilen var mı? – evilcelery

+0

Evet, bir setTimeout yapmayı da düşünmekteydim - kesinlikle işe yarayacak ama korkunç derecede hacky hissettiriyor. – Skilldrick

+0

Görünüşe göre, * bir öğe eklendiğinde * olayı olan olaylar * (http://en.wikipedia.org/wiki/DOM_events) ör. 'DOMNodeInserted', ancak IE tarafından desteklenmiyor. Her zamanki gibi. Bazı daha fazla bilgi: http://stackoverflow.com/questions/2143929/domnodeinserted-equivalent-in-ie – Skilldrick

5

jQuery Tools Tooltip eklentisini ayarlayan benzer bir sorunla karşılaştım. Ama iyi çalışan çok farklı bir yaklaşım vardı: görüşte özel bir olayı tetiklemek. Bildiğim kadarıyla, omurgaya yerleştirilmiş 'dom'a yerleştirilmiş' bir olay yok, ben de bunu kendim yaptım.Ben bir yönlendirici kullanmanız yok ama yukarıda modifiye kodu şöyle görünecektir:

// In the router: 
action: function() { 
    var container = $('#container'); 

    container.append(myView.render().el)); 
    myView.trigger('rendered'); 
}, 

// In the view: 
initialize: function() { 
    this.bind('rendered', this.afterRender, this); 
}, 
render: function (container) { 
    $(this.el).append($.tmpl(this.template, attrs)) 
    return this; 
}, 
afterRender: function() { 
    $('label', this.el).inFieldLabels(); 
} 

Ben avantajı görünümü onun kabın cahil kalmasını olduğunu varsayalım. Dezavantajı, ekstra bir satır veya iki kod gibi olmasıdır. Ancak, çok fazla eklenti kurmanız veya öğenin DOM içinde olmasını gerektiren daha fazla şey yapmanız gerekiyorsa, iyi çalışır (ve mantıksal olarak ayrılır).

Aslında @ Skilldrick'in kapsayıcıyı görüntüye geçirme yöntemini seviyorum, ancak yine de, ebeveyn görünümünün çocukların yerleştirilmesinden sorumlu olmasının mantıklı olduğunu hissediyorum. Ben Backbone için yeniyim, lütfen yorum yapmaktan çekinmeyin. Böylece kodunu değiştirmek" ile esasen demek istiyorum -

render: function() { 
    $(this.el).html(this.template(this.model.toJSON())); 
    $('#email1dropdown', this.el).dropdownify(); 

    return this; 
}, 
+0

Bu ilginç bir fikir, ancak yönlendiricinin, oluşturulduğu görünümü anlatmak zorunda olduğu fikrini beğenmiyorum. Bu sadece temelde bakış hakkında bilmesi gereken bir şey gibi görünüyor! – Skilldrick

+0

Konteynır elemanını görünümden uzak tutmak istiyorsanız iyi bir uzlaşmadır. – Skilldrick

+0

Doğru, bu bir tradeoff. Gerçekten bir yöne veya başka birine doğru çekmiyorum. Uygulamamı yürütürken bir şey yoluma girerse tekrar yorum yaparım. –

2

Ben işlemek işlevinde jQuery için bağlam belirterek sadece benim jQuery eklentisi için çalışmak üzere bu elde edebildi öğe "render" yönteminde DOM'a eklenir. Bu arada, '$' ('label', this.el) `için kestirme olan bu '$' ('label')` dır.
+2

"Bu. $ (" # Email1dropdown ") kısa yolunu kullanın. – Matthew

İlgili konular