2015-11-23 16 views
7

arkadaş devs!Tepki: AppStore dinleyicisi bir işlev olmalı

Egghead'deki eğiticiler sayesinde Flux/React içine kazıyorum. React'un hareket ettiğini duymuş olsam da, bu dersleri takip ederken React kütüphanesindeki bazı değişikliklerle karşılaştım.

Şimdiye kadar hepsini tamir edebildim. Şimdi, Mağaza ile ilgili bir tuğla duvara koştum. Öğretici olarak, kullanıcının alışveriş sepetine bir şeyler ekleyebileceği bir alışveriş sepeti yapıyorum. Bu karmaşık değil. Asıl eklenti çalışır, ancak yeniden oluşturma tetiklenmez.

addChangeListener: function(callback) { 
    this.on(CHANGE_EVENT, callback); 
}, 

Yakalanmayan TypeError sonuçlanır: Aşağıdaki kodu (tam kod yanı aşağıda listelenecek) ilave hata veriyor dinleyici işlevi olmalıdır. Geri arama parametresi tanımlanmamıştır (yani sorunun nerede olduğu budur). Ancak, yeni React'ın çalışma şeklinden daha fazlasım olduğu için, problemi bulmakta zorlanıyorum. Aşağıdaki pasajı öğreticisindeki Store: Bu Egghead.io bir öğretici gelen kodu olduğunu

var AppStore = assign(EventEmitter.prototype, { 

    emitChange: function() { 
     this.emit(CHANGE_EVENT); 
    }, 
    addChangeListener: function(callback) { 
     this.on(CHANGE_EVENT, callback); 
    }, 
    removeChangeListener: function(callback) { 
     this.removeChangeListener(CHANGE_EVENT, callback); 
    }, 
    getCart: function() { 
     return _cartItems; 
    }, 
    getCatalog: function() { 
     return _catalog; 
    }, 
    getCartTotals: function() { 
     return _cartTotals(); 
    }, 
    dispatcherIndex: AppDispatcher.register(function (payload) { 
     var action = payload.action; 

     switch(action.actionType) { 
      case AppConstants.ADD_ITEM: 
       _addItem(payload.action.item); 
       break; 
      case AppConstants.REMOVE_ITEM: 
       _removeItem(payload.action.index); 
       break; 
      case AppConstants.INCREASE_ITEM: 
       _increaseItem(payload.action.index); 
       break; 
      case AppConstants.DECREASE_ITEM: 
       _decreaseItem(payload.action.index); 
       break; 
     } 

     AppStore.emitChange(); 

     return true; 
    }) 
}); 

not alın ve hiçbir-şekilde sahibi benim (ve onlar bu yüzden kaldıracaktır isterseniz kod adı geçen).

Daha fazla kod veya açıklama gerekirse, mecbur kaldığım için mutlu olurum!

sayesinde insanlar :)

DÜZENLEME 1: değiştirmek dinlemek gerekiyordu bileşeni değil yapar: Bana göre

var Cart = React.createClass({ 

    getInitialState: function() { 
     return cartItems(); 
    }, 
    componentWillMount: function() { 
     debugger; 
     AppStore.addChangeListener(this.onChange); 
    }, 
    componentDidMount: function() { 
     debugger; 
     AppStore.addChangeListener(this.handleChange); 
    }, 
    handleChange: function() { 
     debugger; 
     this.forceUpdate(); 
    }, 
    _onChange: function() { 
     debugger; 
     this.setState(cartItems()); 
    }, 
    render: function() { 
     var total = 0; 
     var items = this.state.items.map(function (item, i) { 
      var subtotal = item.cost * item.qty; 
      total +=subtotal; 
      return (
       <tr key={i}> 
        <td><RemoveFromCart index={i} /></td> 
        <td>{item.title}</td> 
        <td>{item.qty}</td> 
        <td> 
         <Increase index={i} /> 
         <Decrease index={i} /> 
        </td> 
        <td>${subtotal}</td> 
       </tr> 
      ); 
     }); 

     return (
      <table className="table table-hover"> 
       <thead> 
        <tr> 
         <th></th> 
         <th>Item</th> 
         <th>Qty</th> 
         <th></th> 
         <th>Subtotal</th> 
        </tr> 
       </thead> 
       <tbody> 
        {items} 
       </tbody> 
       <tfoot> 
        <tr> 
         <td colSpan="4" className="text-right">Total</td> 
         <td>${total}</td> 
        </tr> 
       </tfoot> 
      </table> 
     ); 
    } 
}); 
+0

Sorunun küçük, çalışan bir örneğini verebilir misiniz? Ayrıca, kodu görmek için hata ayıklamayı denediniz mi * neden * niçin geri arama null? "AddChangeListener" öğesini nereden arıyorsun? Bir bileşeni var mıyım? – christopher

+0

Yapabilirsem isterdim, ama 20'ish dosyalarından ve gerçek kodun telif hakkı sorunuyla ilgili konuşuyoruz (söz konusu kodun kopyalanması/dağıtılması için sınırların nerede bulunduğundan emin değilim). Temel olarak, 'Appstore.emitChange()' satırını tetikleyen '_addItem (payload.action.item) işlevi çağrılır. Bu da, 'addChangeListener: function (callback)' satırını tetikleyen emitChange: function() 'satırını tetikler. Doğal olarak, geri arama tanımsızdır .. Ama bu konuda React hakkında yeterli bilgi sahibi değilim:/ – Nickvda

+0

"emitChange", 'addChangeListener' işlevini neden/nasıl? Yapmamalıydı. Etkinlik yayıldığında hangi işlev çağrılır? Kodunuzu doğru şekilde bağlayamadınız gibi görünüyor. Bunun React btw ile ilgisi yok. AddChangeListener’in nasıl çağrıldığını bilmiyorsak size gerçekten yardımcı olamayız. –

cevap

2

, bu çoğu çalıştık gibi geliyor desen ama biraz kafanız karıştı. Eklemeniz gereken son bir adım var ve bu aslında bileşenlerinizi mağazanın dışarı çıktığı etkinliklere abone oluyor.

this.emit(CHANGE_EVENT); 

Bu, yalnızca bir şeyi dışarıya itecektir. Kimse dinlemezse, hiçbir şey değişmeyecek, bu yüzden bileşenlerde gerçekten bu olayı dinlemelisiniz.

React.createClass({ 
    componentDidMount: function() { 
     // Called after react has rendered the HTML in the DOM. 
     AppStore.addChangeListener(this.handleChange); 
    }, 

    render: function() { 
     return <div>{AppStore.someData}</div> 
    }, 

    handleChange: function() { 
     this.forceUpdate(); 
    } 
}); 

NOT: benzeyebilecek bir bileşen için

, this.emit addChangeListener çağıran edilmemelidir.yöntemini kullanarak abone olduğunuz geri çağrıları tetiklemelidir. Unutulmaması gereken

Potansiyel İyileştirmeler

  • Bir şey tüm verilerinize AppStore içinde olmasına rağmen bileşenlerin hepsi hakkında tüm verilerin ilgilenecek, olmasıdır. Örneğin, kullanıcı adınızı veren bir Name bileşeniniz varsa, yalnızca NAME_CHANGE_EVENT ile ilgilidir. Her seferinde tekrar küçük bir şey olmak istemezler. React, React tarafından gereksiz bir işlemdir, ancak React hiçbir şeyin değişmediğini ve DOM'ı güncellemediğini gösterir.
+0

Tavsiye için teşekkürler! Yine de bu kalıbın içinde daha iyi bir kavrayış elde etmek için her yerde hata ayıklama :) 'this.emit' tetikleyicileri addChangeListener' diyerek bir hata yaptım, bu doğru değil. Ancak, güncellenmiş olması beklenen bileşenlere bir dinleyici yerleştirdim, ancak bir güncelleme gerçekleştiğinde işlevlerin hiçbiri tetiklenmiyor. Bileşeni OP'de yayınlayacağım. – Nickvda

+0

Ve '_addItem' tanımladınız mı? – christopher

+0

Tamam, bu hata kendi aptallığımdan kaynaklanıyordu. Bu 'this.onChange' olması gereken 'this.onChange' dosyasına _ eklemeyi unuttum. Eklenen işlevlerinizi kaldırdıktan sonra bile yine de bir çekicilik gibi çalışır (nedenini anlamak için cehennem hatalarını ayıklamama rağmen *). Teşekkürler - Cevabınızı çözüm olarak verebiliyorum, çünkü potansiyel iyileştirme sizin için faydalıdır ve beni doğru yöne doğru itmiştir. _addItem(), AppStore uygulamasındaki özel bir işlevde gerçekleşir (derleme sırasında kendi kapsamına sarılırken global kapsamlıdır). Tekrar teşekkürler! – Nickvda