Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for dynamically subscribing to a Backbone Model or Collection? #29

Open
iamdanfox opened this issue Sep 21, 2014 · 4 comments
Open

Comments

@iamdanfox
Copy link

Components often need to react to Backbone models that are introduced during the component's lifecycle. (e.g. a model returned by a function that is stored in this.state).

At present, I just inline the crucial bits from your subscribe and unsubscribe functions. It would be really cool if there was a way to dynamically add another React mixin or somehow 'subscribe' to these models without needing to rewrite it each time

@markijbema
Copy link
Collaborator

Could you show a piece of code where you do this? I think it would be good to bind to the result of a function, instead of to a string referring to a property. Problem is, if it just occurs sometimes in a function, it is hard to guess the lifecycle beforehand; should it unbind on props updating? On state changing? etc.

@iamdanfox
Copy link
Author

I can't paste the code here, but I was writing a FilteredSearchComponent that received a search string and displayed a filtered subset of results. Each result was represented as a backbone model. They were loaded from the server and would magically update with push updates.

In my scenario, I needed the FilteredSearchComponent to re-render if any of the result models changed (because that might change whether they passed the filter).

I did the unbinding at the componentWillUnmount stage since a few unnecessary render calls work fine with React :)

@markijbema
Copy link
Collaborator

Was there a specific reason you were enable to bind on 'change' of the collection?

@iamdanfox
Copy link
Author

That would work perfectly if the result models were returned in a collection (and some logic was moved out of the component). Unfortunately, that isn't always possible, because those resultModels might then end up appearing in multiple collections, which doesn't have great support as far as I can tell...

In all honesty, I think this is quite a small issue, but might be an interesting consideration for future development / refactoring.

I paraphrased the component code below (compiled js also available)...

FilteredSearchComponent = React.createClass
  propTypes:
    filterString: React.PropTypes.string.isRequired

  getInitialState: ->
    loading: true
    results: []

  componentWillMount: ->
    listOfModels = App.dataLayer.checkOutAllPushModels()
    for model in listOfModels # would like to get rid of this... listen to all and autounbind
      model.on 'change', (=>@forceUpdate()), @
    @setState
      loading: false
      results: listOfModels

  componentWillUnMount: ->
    for model in @state.results
      App.dataLayer.returnPushModel model
      model.off 'all', null, @   # would like to get rid of this too 

  render: ->
    matchesFilterString = (model) ->
      return model.matchesFilterString(@props.filterString)

    <div>
      { if @state.loading
          <Spinner />
        else
          @state.resultModels.filter(matchesFilterString).map (model) -> 
            <ResultRow model={model} /> }
    </div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants