On Github stevekane / component-talk
Javascript developer living in Bucktown and currently working for Mantra, Inc building MVPs for new startups.
//handlebars template {{secondsViewed}}
//javascript code App.OurTimetrackerComponent = Ember.Component.extend({ msViewed: 0, oldTime: null, newTime: null, secondsViewed: function () { var msViewed = this.get('msViewed'); return Math.round(msViewed); }, startTimer: function () { Ember.run.later(this, function () { var newTime = Date.now() , oldTime = this.get('oldTime') || Date.now() , detaMs = newTime - oldTime; this.incrementProperty('msViewed', deltaMs); this.set('oldtime', newtime); }, 500); }.on('didInsertElement') });
{{! display the time a user has spent on this view }} {{our-timetracker}}
{{our-timetracker action="logTimeStamp"}}
//snippet from our origin timetracker startTimer: function () { Ember.run.later(this, function () { var newTime = Date.now() , oldTime = this.get('oldTime') || Date.now() , deltaMs = newTime - oldTime; this.incrementProperty('msViewed', deltaMs); //new this.sendAction("action", this.get('msViewed')); //endnew this.set('oldTime', newTime); }, 500); }.on('didInsertElement')
{{our-timetracker action="logTimeStamp"}}
App.SomeController = Ember.Controller.extend({ actions: { logTimeStamp: function (ms) { var lsTimeStamps=localStorage['timestamps'] || "[]" , timeStamps=JSON.parse(lsTimeStamps) , stringifiedTimeStamps; timeStamps.push(ms); stringifiedTimeStamps=JSON.stringify(timeStamps); localStorage['timestamps']=stringifiedTimeStamps); } } });
App.SomeController = Ember.Controller.extend({ actions: { logTimeStamp: function (ms) { this.websocket.send(ms); } } });
App.TimeGraphComponent = Ember.Component.extend({ actions: { logTimeStamp: function (ms) { //weird d3 code belongs here } } });@heyjinkim's blogpost w/ real implementation
{{! some.handlebars }} {{! template for somecontroller and someview }} {{our-timetracker action="logTimeStamp" msViewed=view.msOnPage}} {{our-timegraph data=view.msOnPage}}
App.SomeView = Ember.View.extend({ msOnPage: 0 });
{{our-timetracker action="logTimeStamp" msViewed=view.msOnPage}}
changes to bound properties are propagated to every part of your app that depends on them...for free.
{{our-timetracker outputBus=timeBus}} {{our-timegraph inputBus=timeBus}}
App.SomeController = Ember.Controller.extend({ //not an ember builtin! timeBus: App.Bus.create() }); App.TimetrackerComponent = Ember.Component.extend({ //psuedocode for brevity onTick (ms): function () { var outputBus = this.get('outputBus'); outputBus.push({ timeStamp: ms, otherData: //something }); } }); App.TimegraphComponent = Ember.Component.extend({ didInsertElement: function () { var inputBus = this.get('inputBus'); inputBus.on('data', function (data) { this.graph(data.timeStamp); }); } });
//data is a blob of weather data fetched by the Route App.WeatherController = Ember.Controller.extend({ cityName: "Chicago", activeDateTime: Date.now(), activeDaysData: function () { var activeDateTime = this.get('activeDateTime') , data = this.get('data'); this.get('data').filterProperty('date', activeDateTime); }.property('activeDateTime', 'data'), isMetric: true, } });
Computes current temperature
Displays City Name, Current Date and Time, Summary
{{weather-overview cityName=cityName dateTime=activeDateTime data=activeDaysData}}
Computes and displays average windspeed, humidity, precipitation
{{weather-daily-averages data=activeDaysData isMetric=isMetric}}
Computes current temperature and activeDays overview
Displays temperature, and graphic based on overview
Toggles "isMetric" value via clicks
{{weather-graphical-overview data=activeDaysData dateTime=activeDateTime isMetric=isMetric}}
Has an internal state to track what is being displayed
Contains "controls" component and "graph component"
{{weather-graph-wrapper data=activeDaysData isMetric=isMetric}}
Computes/displays range of a type of data
State change will cause graph to render new Data
{{weather-graph data=activeDaysData state=state isMetric=isMetric}}We could further enhance this component by passing in a range of hours, a scale, or even display properties
Changes "state" based on clickable buttons
NOTE: this is really just a set of "tabs" and could be further generalized
{{weather-graph-controls state=state}}
Graph component may be used elsewhere and have its state driven by other means
Controls component may be used to drive some other state, perhaps tabs?
Create a "daily overview" component
Create a "weekly overview list" component that USES the "daily overview" component in its template
{{! weather-weekly-overview template }} {{#each day in days}} {{weather-daily-overview data=day.data}} {{/each}}
Clicking a "daily overview" will affect the activeDateTime
Daily overview component may be used elsewhere
Weekly overview is concerned with determining list of daily data
Daily overview is concerned with computing/displaying daily data
Let's group the first three components into "overview wrapper" component as we have done in with the previous arrangements
{{! weather.handlebars }} {{weather-overview-wrapper cityName=cityName dateTime=activeDateTime data=activeDaysData isMetric=isMetric}} {{weather-graph-wrapper data=activeDaysData isMetric=isMetric}} {{weather-weekly-overview data=data dateTime=activeDateTime isMetric=isMetric}}