2014-09-26 14 views
6

Chcę utworzyć aplikację przy użyciu pliku React.js. Chcę, aby można było łatwo dostosować go do świata zewnętrznego (np. Pisząc usercripts). Pomysł, którego próbowałem użyć, polega na wprowadzeniu pewnych specjalnych właściwości w stanie elementu głównego (np. sidebarItems lub playlistCreatedHooks), aby programiści addonów mogli dodać coś takiego. Moje pytania brzmią: czy jest to dobry sposób na zrobienie tego, czy istnieje Right Way ™, aby osiągnąć coś podobnego do mojego celu i, w końcu, w jaki sposób twórcy dodatków będą mieli dostęp do tych rekwizytów?Uzyskiwanie dostępu Stan reakcji z zewnątrz

Odpowiedz

8

Jedną z opcji są obserwowalne. Zasadniczo jest to obiekt, na którym można słuchać zmian i utworzyć zmianę. Można również emitować inne zdarzenia, takie jak zdarzenie "add" na stronie data.playlists, aby utworzyć api, które chcesz udostępnić.

// data.js 
var data = { 
    sidebarItems: Observable([]), 
    playlists: Observable([]) 
}; 

// app.js 
var App = React.createComponent({ 
    mixins: [data.sidebarItems.mixin("sidebar")], 
    render: function(){ 
    return this.state.sidebar.map(renderSidebarItem); 
    } 
}); 

/// userscript.js 

// causes the view to update 
data.sidebarItems.set(somethingElse); 

// run when someone does data.playlists.set(...) 
data.playlists.on('change', function(playlists){ 

}); 

// an event you could choose to emit with data.playlists.emit('add', newPlaylist) 
data.playlists.on('add', function(newPlaylist){ 

}); 

Oto przykład (przetestowane) realizacja obserwowalnych stosowane powyżej, z dodatkową funkcją generowania reakcji składnika wstawek.

var events = require('events'); // or some other way of getting it 
var Observable = function(initialValue){ 
    var self = new events.EventEmitter(); 
    var value = initialValue; 

    self.get = function(){ return value }; 
    self.set = function(updated){ 
    value = updated; 
    self.emit('change', updated); 
    }; 
    self.mixin = function(key){ 
    var cbName = Math.random().toString(); 
    var mixin = { 
     getInitialState: function(){ var o = {}; o[key] = value; return o }, 
     componentDidMount: function(){ 
     self.on('change', this[cbName]); 
     }, 
     componentWillUnmount: function(){ 
     self.removeListener('change', this[cbName]); 
     } 
    } 
    mixin[cbName] = function(){ 
     var o = {}; o[key] = value; this.setState(o); 
    }; 
    return mixin; 
    } 

    return self; 
} 
+0

Whoa, wygląda super, dzięki! – Ale

1

Oto moje rozwiązanie. Dzięki temu obserwowalne stan składników React jest automatycznie aktualizowany (wraz z jego konsekwencjami, jak ponowne renderowanie komponentu), a nawet można nasłuchiwać zmian poza reakcją, dzięki metodzie .on.

var eventEmitter = { 
    _JQInit: function() { 
     this._JQ = jQuery(this); 
    }, 
    emit: function(evt, data) { 
     !this._JQ && this._JQInit(); 
     this._JQ.trigger(evt, data); 
    }, 
    once: function(evt, handler) { 
     !this._JQ && this._JQInit(); 
     this._JQ.one(evt, handler); 
    }, 
    on: function(evt, handler) { 
     !this._JQ && this._JQInit(); 
     this._JQ.bind(evt, handler); 
    }, 
    off: function(evt, handler) { 
     !this._JQ && this._JQInit(); 
     this._JQ.unbind(evt, handler); 
    } 
}; 

var Observable = function(initialValue, name) { 
    var self = eventEmitter; 
    var name = name; 
    var obj = { 
     value: initialValue, 
     ops: self 
    }; 

    self.get = function() { 
     return obj.value 
    }; 

    self.set = function(updated){ 
     if(obj.value == updated) 
      return; 

     obj.value = updated; 
     self.emit('change', updated); 
    }; 

    self.mixin = function() { 
     var mixin = { 
      getInitialState: function() { 
       var obj_ret = {}; 
       obj_ret[name] = obj; 

       return obj_ret; 
      }, 
      componentDidMount : function() { 
       self.on('change', function() { 
        var obj_new = {}; 
        obj_new[name] = obj; 

        this.setState(obj_new); 
       }.bind(this)); 
      } 
     }; 

     return mixin; 
    }; 

    return self; 
}; 

przykład (stosując to pokazano na alert w innym urządzeniu): // obserwowalnych startowych alert_msg = obserwowalnych ('' 'alertmsg');

var ConfirmBtn = React.createClass({ 
    mixins: [alert_msg.mixin()], 
    handleConfirm: function(e) { 
     e.preventDefault(); 

     this.state.alertmsg.ops.set(null); 

     if(! $('#cgv').is(':checked')) { 
      this.state.alertmsg.ops.set('Please accept our terms of conditions'); 
      return; 
     } 
    } 
} 

var AlertPayment = React.createClass({ 
    mixins: [alert_msg.mixin()], 

    render: function() { 
     var style = (this.state.alertmsg === null) ? {display: 'none'} : {display: 'block'}; 

     return (
      <div style={style} className="alertAcceptTerms"> 
       {this.state.alertmsg.value} 
      </div> 
     ); 
    } 
}); 

Nadzieja pomaga

Powiązane problemy