2011-10-04 27 views
7

Geçerli uygulamamda backbone uygulamasının uygulamasında eksik görünen çevrelerde dolaşıyorum. Sorun, sayfa için çeşitli alt görünümleri (bir grafik, bir bilgi tablosu, vb.) Başlatan bir master AppView'um var. Benim arzum, gezinirken iletilen bir parametre bayrağına bağlı olarak sayfanın düzenini değiştirebilmektir.Omurga Görünümü Yuvalama

Karşılaştığım şey, şablonun oluşturulduktan sonra yer alacağı dom öğelerine gönderme yapan alt görünümlerin, ana AppView başlatma işlemi sırasında bu öğelere erişemediği bir durumdur. Öyleyse asıl soru, her olay için doğru dom elemanlarının doğru şekilde kurulmasını sağlamak için nasıl bir süreç oluşturduğunu nasıl temin ederim?

Aşağıdaki kodla, LayoutView'umdaki bir model değişikliğine bağlı bir etkinliğim varsa, düzen oluşturulur, ancak sonraki görünümler düzgün şekilde oluşturulmaz. Kibirlendiğim bir şey, tüm görünümleri .el 'değerlerini html yapısı içindeki statik bir öğeye ayarlamaktı. Bu, gerçekleşmesini sağlar, ancak '.el' kullanılarak sağlanan güzel kapsam belirleme yeteneğinden uzaklaşır.

Örnek Kod:

//Wrapped in jquery.ready() function... 
//View Code 
GraphView = Backbone.View.extend({ // init, model bind, template, supporting functions}); 

TableView = Backbone.View.extend({ // init, model bind, template, supporting functions}); 

LayoutView = Backbone.view.extend({ 
    initialize: function() { 
    this.model.bind('change:version', this.render, this); 
    }, 
    templateA = _.template($('#main-template').html()), 
    templateB = _.template($('#secondary-template').html()), 
    render: function() { 
    if ('main' == this.model.get('version')) { 
     this.el.html(this.templateA()); 
    } else { 
     this.el.html(this.templateB()); 
    } 
    }, 
}); 

MainView = Backbone.View.extend({ 
    initialize: function() { 
    this.layoutView = new LayoutView({ 
     el: $('#layoutContainer'), 
     model: layout, 
    }); 
    this.graphView = new GraphView({ 
     el: $('.graphContainer'), 
     model: graph 
    }); 
    this.tableView = new TableView({ 
     el: $('#dataTableContainer', 
     model: dataSet 
    }); 
    }, 
}); 

// Model Code 
Layout = Backbone.Model.extend({ 
    defaults: { 
    version: 'main', 
    }, 
}); 

Graph = Backbone.Model.extend({}); 
dataSet = Backbone.Model.extend({}); 

// Router code... 

// Fire off the app 
AppView = new MainView($('#appContainer')); 
// Create route, start up backbone history 

HTML: Kolaylık olması açısından Sadece iki düzenleri arasında div'leri yeniden düzenlenmiş.

<html> 
    <head> 
    <!-- include above js and backbone dependancies --> 
    </head> 
    <body> 
    <script type="text/template" id="main-template"> 
     <div class="graphContainer"></div> 
     <div class="dataTableContainer"></div> 
     <div>Some other stuff to identify that it's the main template</div> 
    </script> 
    <script type="text/template" id="secondary-template"> 
     <div class="dataTableContainer"></div> 
     <div>Rock on layout version two!</div> 
     <div class="graphContainer"></div> 
    </script> 
    <div id="appContainer"> 
     <div id="nav"> 
     <a href="#layout/main">See Layout One</a> 
     <a href="#layout/secondary">See Layout Two</a> 
     </div> 
     <div id="layoutContainer"></div> 
    </div> 
    </body> 
</html> 

Herhangi birinizin sahip olabileceği içgörüyü/girdiyi takdir edin. Teşekkürler!

+0

Sadece FYI, kodunuzda bir sürü yazım hatası var - bunların gerçek sözdizimi hataları değil, kopyala/yapıştır sorunları olduğunu varsaymak güvenli midir? – nrabinowitz

+0

Blame kopyala/yapıştır, alttaki mantık, umarım hala iletiliyor. Bunu işaret ettiğin için teşekkürler. – aztechy

cevap

8
Örneğinizde çok fazla eksik kodunuz var, ancak doğru bir şekilde anlarsam sorun, LayoutView tarafından oluşturulan HTML'ye bağlı görünümleri oluşturmaya çalışıyor olmanızdır, ancak düzen, zaman uyumsuz olarak seçildiğinde model güncellendi, bu nedenle LayoutView henüz oluşturulmadı.

Orada bu çoklu yaklaşımlar, ama genel olarak (hemen hemen her şeyi Backbone ilişkili olduğu gibi) şunlardır:

  • Ben oluşturulmakta olan bir "üst" görüşüne dayanan görünüm varsa ben olacak Bu görünümleri üst görünümde oluşturma ve oluşturma sorumluluğunu - bu durumda, , değil MainView.

  • Üst, eşzamansız olarak oluşturuluyorsa, bu örneklemenin geri çağrıda gerçekleştirilmesi gerekir - burada, LayoutView.render() yöntemi. - Eğer initialize() yılında subviews örneğini olabilir ve el özelliğini ayarlayın Eğer örnekleme bir el geçmek gerekmez

    LayoutView = Backbone.view.extend({ 
        initialize: function() { 
        this.model.bind('change:version', this.render, this); 
        // you probably want to call this.model.fetch() here, right? 
        }, 
        templateA: _.template($('#main-template').html()), 
        templateB: _.template($('#secondary-template').html()), 
        render: function() { 
        if ('main' == this.model.get('version')) { 
         this.el.html(this.templateA()); 
        } else { 
         this.el.html(this.templateB()); 
        } 
        // now instantiate and render subviews 
        this.graphView = new GraphView({ 
         // note that I'm using this.$ to help scope the element 
         el: this.$('.graphContainer'), 
         model: graph 
        }); 
        this.tableView = new TableView({ 
         el: this.$('.dataTableContainer'), 
         model: dataSet 
        }); 
        // you probably need to call graphView.render() 
        // and tableView.render(), unless you do that 
        // in their initialize() functions 
        }, 
    }); 
    

    Not:

Yani bu gibi bir kod yapılandırabileceğinize subview.render(). Artık, MainView.initialize()'da, şimdi yaptığınız gibi örnek oluşturabilir ve eşzamansız hale getirmek için görünümleri LayoutView geçirebilirsiniz. Ama bence yukarıdaki yaklaşım muhtemelen daha temiz.

+0

Cevabınız için teşekkür ederiz.Oluşturma işleminden sonra LayoutView içindeki alt görünümleri çağırmanın bu uygulamasıyla oynadım. Çeşitli alt görünümlerin, model değişim durumlarında güncellenen kendi render haline sahip olduğu varsayımında doğrusunuz. Bazı tuhaf nedenlerden ötürü getirildikten sonra görünse de, birkaç kez çağrı çağrılıyordu. Birden çok kez çeşitli altyazıları verimsiz bir şekilde eklediğimi düşünmem için beni tetikliyor. Verilerimi getirdikten sonra birden fazla işlem çağrısına neden olan başka şeyleri bulmak zorunda kalabilirim. Tekrar teşekkürler! – aztechy

+0

Bu yardımcı oldu - Sık sık zaten yüklü değil, bir alt görünümü başlatmak için mantığa ihtiyacım var, bu sorun olabilir. (BTW, cevabı beğenirseniz, onay işaretini sola çevirerek onaylayabilirsiniz :) – nrabinowitz

+0

Doğru, alt görünümü oluşturmak için mantık oluşturmak gereklidir. Ne yazık ki, layoutview.render() içindeki alt görünümlerin başlatılması, başlangıç ​​ayar kurulumunda tanımlanan model değişikliği olaylarında, düzgün bir şekilde işlenemeyen alt görünümlere neden oluyor. Temel olarak, bir görüntünün model durumunun, navigasyonda aynı kaldığı durumda, yukarıdaki alt bölüm, yukarıdaki işlem nedeniyle boş bir şablonun üzerine yazılır. Bunun mantık olayının yeniden işlenmesini gerektirebileceğini düşünüyorum. – aztechy