implement reactjs history

This commit is contained in:
Eric Hulburd
2016-03-04 13:59:34 -06:00
parent 5b218f6518
commit aa885f331c
27 changed files with 549 additions and 546 deletions

View File

@@ -1,62 +1,67 @@
import React from 'react';
import { createHistory } from 'history';
import ObjectUtil from './../../../shared/utils/object';
import Templates from 'config/templates';
import House from './../../models/house';
import PowerDatum from './../../models/power_datum';
import {RouteHelper} from './../routes';
import StateManager from './../state_manager';
class LayoutComponent extends React.Component {
constructor(props, context){
super(props, context);
this.renders = 0;
this.state = {
var layout = this;
layout.state = {
loading_houses: true,
houses: null,
house: null,
loading_house_data: true
};
this.updates = 0
dataset: null,
year: null,
view: null
}
}
get house(){
return this.props.location.state && this.props.location.state.house;
return this.state_manager && this.state_manager.state.house;
}
componentDidMount() {
var layout = this;
House.ensureHouses().then((houses)=>{
var house = null;
if (layout.props.params.house_id != undefined){
house = houses.find((h)=>{ return h.data.id == layout.props.params.house_id; });
}
layout.setState({
houses: houses,
loading_house_data: false
houses: houses,
loading_houses: false
}, ()=>{
if (house){
var route_helper = new RouteHelper(layout.context.router, layout.props, {house: house});
route_helper.updateRoute();
}
layout.state_manager = new StateManager(layout.props.createHistory, houses);
layout.state_manager.history.listen((location)=>{
layout.state_manager.updateStateFromUrl(location, layout);
});
});
});
}
componentDidUpdate(){
syncFromStateManager(fnStateSet){
var layout = this;
this.updates += 1;
console.log(this.updates, ') LayoutComponent#componentDidUpdate');
layout.setState(layout.state_manager.state, fnStateSet);
}
setHouse(event){
var layout = this,
house_id = event.target.value;
if (!layout.house || layout.house.id != house_id){
House.ensureHouses().then((houses)=>{
var new_house = houses.find((h)=>{ return h.data.id == house_id }),
route_helper = new RouteHelper(layout.context.router, layout.props, {house: new_house});
route_helper.updateRoute();
});
}
if (layout.state_manager.state.house_id == house_id) return false;
layout.state_manager.setParams({house_id: house_id}, layout);
}
setParam(event){
var layout = this,
param = event.target.dataset.param,
value = event.target.dataset.value,
update = {};
update[param] = value;
if (value == layout.state_manager.state[param]) return false;
layout.state_manager.setParams(update, layout);
}
refreshData(){
@@ -78,8 +83,4 @@ class LayoutComponent extends React.Component {
}
}
LayoutComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default LayoutComponent;

View File

@@ -1,11 +1,97 @@
<rt-require dependency="./../energy/energy.component" as="EnergyComponent"/>
<rt-require dependency="./../power/power.component" as="PowerComponent"/>
<div id="layout">
<div class="alert alert-warning" rt-if="this.state.loading_house_data">Retrieving houses...</div>
<div rt-if="!this.house" id="about">
<div class="panel panel-default">
<div class="panel-heading">About</div>
<div class="panel-body">
<p>This is a Spike bundle prototype using the following libraries:</p>
<ul>
<li>React</li>
<li>React Templates</li>
<li>React Router</li>
<li>LokiJs - persisting API calls to indexedDb</li>
<li>Webpack - hot mode developing and app bundling</li>
<li>Babel - ES6 transpiler</li>
</ul>
<p>The demo app consists of a dataset of 10 houses and 10 years of randomly generated power consumption and production at 15 minute intervals. You can toggle between different houses and time periods to compare and contrast the dataset.</p>
<p>Select a house below to get started.</p>
</div>
</div>
</div>
<div class="alert alert-warning" rt-if="this.state.loading_houses">Retrieving houses...</div>
<h4>Select household:</h4>
<select id="houses_select" rt-if="this.state.houses" class="form-control" onChange="{this.setHouse.bind(this)}" value="{this.props.params.house_id}">
<select id="houses_select" rt-if="this.state.houses && this.state_manager" class="form-control" onChange="{this.setHouse.bind(this)}" value="{this.house_id}">
<option rt-repeat="house in this.state.houses" value="{house.data.id}" key="{house.scoped_id}">{house.data.name}</option>
</select>
<button rt-if="this.house" onClick="{this.refreshData.bind(this)}" class="btn btn-xs btn-default">Refresh House Data</button>
{this.props.children}
<div rt-if="this.house">
<h4>Select dataset:</h4>
<div class="btn-group" role="group">
<button
data-param="dataset"
data-value="energy"
rt-class="{active: this.state.dataset === 'energy'}"
onClick="{this.setParam.bind(this)}"
type="button" class="btn btn-primary">Daily Energy Statistics</button>
<button
data-param="dataset"
data-value="power"
rt-class="{active: this.state.dataset === 'power'}"
onClick="{this.setParam.bind(this)}"
type="button" class="btn btn-primary">15-minute Power Statistics</button>
</div>
<h4>View as:</h4>
<div class="btn-group" role="group">
<button
data-param="view"
data-value="graph"
rt-class="{active: this.state.view === 'graph'}"
onClick="{this.setParam.bind(this)}"
type="button" class="btn btn-primary">Graph</button>
<button
data-param="view"
data-value="table"
rt-class="{active: this.state.view === 'table'}"
onClick="{this.setParam.bind(this)}"
type="button" class="btn btn-primary">Table</button>
</div>
<div rt-if="this.house">
<h4>Select dates:</h4>
<div class="btn-group">
<button
rt-repeat="year in this.house.years"
data-param="year"
data-value="{year}"
key="data-year-{year}"
class="btn-info btn btn-sm"
rt-class="{active: year == this.state.year}"
onClick="{this.setParam.bind(this)}">{year}</button>
</div>
</div><br/>
<EnergyComponent
rt-if="this.state.dataset === 'energy'"
house="{this.state.house}"
loading_energy_data="{this.state.loading_energy_data}"
state_manager="{this.state_manager}"
view="{this.state.view}"
graph_attr="{this.state.graph_attr}"
year="{this.state.year}" />
<PowerComponent
rt-if="this.state.dataset === 'power'"
house="{this.state.house}"
loading_power_data="{this.state.loading_power_data}"
state_manager="{this.state_manager}"
view="{this.state.view}"
month="{this.state.month}"
year="{this.state.year}"
power_range="{this.state.power_range}" />
</div>
</div>