Skip to content
New issue

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

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

Already on GitHub? # to your account

Setup better dependency resolution system #14

Closed
L8D opened this issue Sep 15, 2015 · 1 comment
Closed

Setup better dependency resolution system #14

L8D opened this issue Sep 15, 2015 · 1 comment

Comments

@L8D
Copy link
Member

L8D commented Sep 15, 2015

Goals:

  • Components can specify what stylesheets they need injected (and/or included in the inline <style> tag)
  • Components can specify what route-dependent resources they need to render
  • Components can specify actions/metadata like setting the page title or analytics/logging during initialization
  • Components can specify instances of client-side controllers they need to read from (possibly merged with the route-dependent resources)

Closes #6

@L8D
Copy link
Member Author

L8D commented Sep 21, 2015

Notes:

Using the conventional store system as opposed to having seperate models and controllers gives us more flexibility with how we structure (and query) our models. It also means our components directly depend on stores, instead of having to indirectly declare what controllers would need to be initialized.

Using decorators to annotate what dependencies need to be injected/fetched for components gives us more flexibility in how we store, encode and query that data. It's also more precise and clean. For example, it would be very easy to setup a system for tracking what stylesheets to inject by adding a stylesheet decorator, and from there we can choose whether to incorporate it with the dependency resolution system, or if we want to use a separate system to track and query that.

Some psuedo-code:

// stores/restaurant.js
import {Dispatcher} from 'flux';
import {Store} from 'some-base-store-class';
import {RouteParams} from 'some-place';
import {SomeRestaurantAction} from '../actions/some-restaurant';

import {Restaurant} from '../models/restaurant';

@inject(Dispatcher, RestaurantResolver)
export class RestaurantStore extends Store {
  constructor(dispatcher, restaurant) {
    super(dispatcher);

    this.restaurant = restaurant;

    this.bind(SomeRestaurantAction, this.handleSomeRestaurant);
  }

  handleSomeRestaurant(payload) {
    // ...
  }

  getRestaurant() {
    return this.restaurant;
  }
}

@injectPromise(RouteParams)
export function RestaurantResolver(routeParams) {
  const restaurant = new Restaurant({id: routeParams.restaurant_id});

  return restaurant.fetch().return(restaurant);
}

// components/restaurant{,/index}.js
import React, {Component} from 'react';
import {stylesheet, dependency, listeningTo} from 'some-other-place';
import {RestaurantStore} from '../stores/restaurant';

@stylesheet('restaurant/index')
@dependency({restaurantStore: RestaurantStore})
@listeningTo(['restaurantStore'], 'getStateFromStores') // compiles down to componentWillMount and componentWillUnmount listeners
export class RestaurantComponent extends Component {
  getStateFromStores = () => {
    const {dependencies} = this.context;
    const {restaurantStore} = dependencies;

    return {
      restaurant: restaurantStore.getRestaurant()
    };
  }

  // ...
}

@L8D L8D closed this as completed Oct 2, 2015
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant