2014-09-29 25 views
5

Benim uygulamada, sectionscourse.sectionIds adlı bir özellik bağlantılı bir koleksiyon. İlk yükleme iyi çalışıyor, ancak yönetici panelinde bir bölüm eklerken reaktif olmayan bir katılma sorununa giriyorum. İşte Meteor, abonelikleri yeniden yüklemek için nasıl zorlanır?

rota var:

@route 'adminCourse', 
    path: 'admin/course/:course' 
    waitOn: -> Meteor.subscribe 'course', @params.course 
    data: -> Course.first() 

Ve bölümler ders yayında bulunmaktadır: Ben yaklaşık reactive joins biliyorum ama gerçekten yaklaşım 1. veya 4. kullanamaz

Meteor.publish 'course', (courseId) -> 
    return null if not this.userId 

    # [some permission checks] 

    courses = Course.find courseId 
    sections = Section.find _id: $in: _.flatten courses.map (course) -> course.sectionIds 

    [ courses, sections ] 

izinli kontroller olduğundan (sadece kendi kurslarınızın bölümlerini görebilmelisiniz) (müşteriye fazla yayınlama ve müşteriye katılma). Ayrıca, veri değiştiğinde'u biliyorum, bu yüzden gerçekten reaktif olmak zorunda değil.

Kullanıcı, yeni bir bölüm eklemek için formu gönderdiğinde, Meteor'ın verileri yeniden yüklemesini bilmesini istiyorum (Şu anda bir bölüm eklendikten sonra window.location.reload() yaparak bunu yapıyorum). Meteor ile bunu yapmanın bir yolu var mı? kimin ilgilendiğini İçin

cevap

5

bu gerçekten basitti çıkıyor ve ben şimdi biraz aptal hissediyorum :)

Sadece tekrar Meteor.subscribe() arayarak abonelik yeniden yükleyebilirsiniz. Bunu farklı bir çözümle uğraşırken buldum. Üstelik, aboneliği yeniden başlatan farklı bir URL'ye gitmek için demir yönlendiriciyi kullanıyordum.

Template.sectionForm.events 
    'submit form': (e) -> 
     e.preventDefault() 
     data = SimpleForm.processForm(event.target) 

     section = Section.create(data) 
     this.course.push(sectionIds: section._id) 

     # Reload the subscription to pull in the new section 
     params = Router.current().params 
     Meteor.subscribe 'course', params.producer, params.course 

Ve bu yeni veri seçip olacaktır:

Yani, benim göndermek dinleyici de, yerine window.reload() yapmanın, sadece aşağıdakileri yapabilirsiniz. Yuppi!

+0

Kesinlikle, bu benim soruma cevaptır. Ancak Mitar'ın ana öğenin kimliğini tüm alt gruplara koyma önerisi (konuşma için önceden bir araya getirme) daha iyiydi ve aslında bu yaklaşımı kullanarak sona erdi. – Rijk

7

, benim yayınlama işlevinde observeChanges ekleyerek sabit: sectionIds özelliğinde değişiklikler için

Meteor.publish 'course', (courseId) -> 
    return null if not this.userId 

    # [some permission checks] 

    courses = Course.find courseId 
    sectionIds = _.flatten courses.map (course) -> course.sectionIds 

    handle = courses.observeChanges 
     changed: (id, fields) => 
      if _.has fields, 'sectionIds' 
       addedIds = _.difference fields.sectionIds, sectionIds 
       removedIds = _.difference sectionIds, fields.sectionIds 
       sectionIds = fields.sectionIds 

       _.each addedIds, (id) => @added 'sections', id, Section.first id 
       _.each removedIds, (id) => @removed 'sections', id 

    @onStop -> handle.stop() 

    sections = Section.find _id: $in: sectionIds 

    [ courses, sections ] 

gözlemci kontrolleri ve aramalar abonelik added veya removed yöntemler ya gerçekleştiğinde . Bu birleşmeyi reaktif yapar; courses.sectionIds özelliğine kimlik eklerken, yeni bölüm belgeleri otomatik olarak şimdi istemciye gönderilir.

+2

Temiz.Hala böyle hissettirmek çekirdekte olması gereken bir işlevsellik için çok çalışıyorum. Umarım [onu 1.0 yapar] (https://trello.com/c/BGvIwkEa/48-easy-joins-in-subscriptions). –

+2

Biliyorum ... Meteor, yapamayacağı bir şeye girene kadar harika;) – Rijk

+0

@DanDascalescu bağlantının doğru olduğundan emin misin? Herhangi bir girişime işaret ediyor gibi görünmüyor. – Rijk

3

sadece meteor-related paket olabilir:

Meteor.publish 'course', (courseId) -> 
    # verify that courseId is really an ID and not {} or something else 

    return unless @userId 

    @related (course) -> 
    # [some permission checks] 

    Section.find 
     _id: 
     $in: course.sectionIds 
    , 
    Course.find courseId 

Burada o courseId maçlar sadece bir ders varsayalım. Dolayısıyla meteor ile ilgili çalışmalar sadece bire-çok ilişkiler ile çalışır. Yukarıdaki kodunuzda çok fazla şey yaptınız. Başka bir yol, tüm bu belgelerin (soru, seçenek, adım, vb.) Ana kimliğinizin yani ders kimliğinizin olmasıdır. Ve sonra, tüm bu belgeleri ders kimliğine göre filtreleyin ve bunu istemciye yayınlayın, sonra istemcide bunu istediğiniz hiyerarşi içinde gösterin. Dolayısıyla, ilişkileri okuma zamanında hesaplamaya çalışmak yerine, ilişkileri yazma zamanında hesaplarsınız ve bu ilişkinin kimliğini ilgilendiğiniz tüm belgelere saklarsınız.

Yasal Uyarı: Bu paketin yazarı ben değilim.

+0

Ayrıca, [PeerDB] (https://github.com/peerlibrary/meteor-peerdb) paketine de bakabilirsiniz. – Mitar

+0

Teşekkürler Mitar, Kesinlikle kontrol edeceğim. Sadece bir çok ilişki var: kurs 1 - n bölüm 1 - n adım. 'Homebrew' çözümümüzü hepsine uyguladım ve tek linkler için çalışıyor (yeni bölümler ve adımlar otomatik olarak ortaya çıkıyor) ama henüz tam olarak tepki vermiyor: yeni bir bölüme yeni bir adım eklendiğinde, O görünmüyor (Sanırım yeni bölüm sonuç kümesinde değişiklik gözlemlenmiyor). "Meteorla ilgili" ilişkilere yer verebilir misiniz? – Rijk

+0

Belki de iç içe geçmiş ilişkileri test etmedim. Bence yaklaşımı yeniden düşünmelisin. İşe koyulmasanız bile, bir abone oluşturduğunuzda yaptığınız sorgunun sayısı çok büyüktür, eğer n bölümleriniz varsa, sorgularda ek birleştirme sihri ve optimizasyonları olmadıkça, adımlar için n sorgular oluşturacaksınız. Ama sonra soru şudur: Eğer birleşimleri kullanmak istiyorsanız neden MongoDB kullanıyorsunuz. Veya: MongoDB'de neden böyle bir şema kullanıyorsunuz? Bence ilişkisel şema yapıyorsun. Alt belgeleri ve dizileri kullanmayı deneyin. MongoDB'nin bütün fikri bir sorgulama yapmaktır. – Mitar

İlgili konular