Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hijacking Hacker News with Ember.js
Search
Godfrey Chan
March 03, 2015
Programming
640
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Hijacking Hacker News with Ember.js
EmberConf 2015
Godfrey Chan
March 03, 2015
More Decks by Godfrey Chan
See All by Godfrey Chan
Virtual EmberConf 2022: Platform State of the Union
chancancode
0
310
Virtual EmberConf 2021: Platform State of the Union
chancancode
0
240
Virtual EmberConf 2020: Platform State of the Union
chancancode
1
390
Thinking in TypeScript
chancancode
0
320
The Lifecycle of a Rails Request
chancancode
3
15k
Dropping Down To The Metal™ (2018)
chancancode
0
170
Using Skylight to Solve Real-World Performance Problems
chancancode
1
460
Prying Open The Black Box (EmberConf 2018)
chancancode
0
440
Bending The Curve: Putting Rust in Ruby with Helix
chancancode
2
2.9k
Other Decks in Programming
See All in Programming
What We Talk About When We Talk About XP
m_seki
2
390
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
690
Hono + Inertia + React で LP を構築した話
oukayuka
2
220
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
130
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
290
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
Press start. Python's next generation.
willingc
PRO
3
320
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
170
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
130
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
180
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
Featured
See All Featured
Google's AI Overviews - The New Search
badams
0
1.6k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
680
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
690
Code Reviewing Like a Champion
maltzj
528
40k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Exploring anti-patterns in Rails
aemeredith
3
500
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
200
Music & Morning Musume
bryan
47
7.4k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
65k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
Transcript
@chancancode Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
BEFORE AFTER image courtesy of TOM DALE “THE FACE OF
OUR NATION” Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
52 °F Wednesday, 4 March, 15
52 °F 52 °Freedom Wednesday, 4 March, 15
52 °F 52 °Freedom DEGREES OF FREEDOM Wednesday, 4 March,
15
52 °F 52 °Freedom 11 °cDEGREES OF FREEDOM Wednesday, 4
March, 15
52 °F 52 °Freedom 11 °CANADA 11 °cDEGREES OF FREEDOM
Wednesday, 4 March, 15
52 °F 52 °Freedom 11 °CANADA 11 °cDEGREES OF FREEDOM
“It is currently 11 degrees, in canada.” Wednesday, 4 March, 15
var isEmpty = false; var isLoaded = true; Wednesday, 4
March, 15
var isEmpty = false; var isLoaded = true; var emptyEh
= false; var loadedEh = true; Wednesday, 4 March, 15
>> require 'canada' => true >> [].empty_eh? => true >>
[1,2,3].empty_eh? => false Wednesday, 4 March, 15
gem install canada Wednesday, 4 March, 15
alias npm=gem npm install canada Wednesday, 4 March, 15
Wednesday, 4 March, 15
To Rem 3 Terrible Hacks Wednesday, 4 March, 15
To Rem 3 Terrible Hacks LOL Wednesday, 4 March, 15
You Should A Design Pattern ace Wednesday, 4 March, 15
You Should A Design Pattern YASSS ace Wednesday, 4 March,
15
This Slide? What Colors Are Wednesday, 4 March, 15
This Slide? What Colors Are POLL Wednesday, 4 March, 15
Wednesday, 4 March, 15
DS.Adapter Wednesday, 4 March, 15
ADAPTER PATTERN Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
Wednesday, 4 March, 15
var CanadianSensor = { getTemperature: function() { // Measures temperature
in °C } }; Wednesday, 4 March, 15
function FreedomMonitor(sensor) { setInterval(function() { // Expects °F if (sensor.readTemperature()
> 100) { ... } }, 1000); }; var CanadianSensor = { getTemperature: function() { // Measures temperature in °C } }; Wednesday, 4 March, 15
function CanadianAdapter(sensor) { this.sensor = sensor; }; CanadianAdapter.prototype = {
readTemperature: function() { return this.sensor.getTemperature() * 1.8 + 32; } }; // Use it! new FreedomMonitor( new CanadianAdapter(CanadianSensor) ); Wednesday, 4 March, 15
DEMO TIME! Wednesday, 4 March, 15
chancancode / hn-reader Wednesday, 4 March, 15
GETTING THE DATA Wednesday, 4 March, 15
Wednesday, 4 March, 15
$.get("/news").then( function(html) { var stories = []; $(html).find("tr .title a").each(
function (_, $link) { stories.push({ title: $link.text(), url: $link.attr('href') }); }); ... return stories; }); Wednesday, 4 March, 15
Ember Data ( DATA STORE ) JSON API ( DATA
SOURCE ) Wednesday, 4 March, 15
Ember Data ( DATA STORE ) HACKER NEWS HTML SCRAPPER
( DATA SOURCE ) Wednesday, 4 March, 15
Ember Data ( DATA STORE ) HACKER NEWS HTML SCRAPPER
( DATA SOURCE ) Wednesday, 4 March, 15
DS.Adapter DS.Serializer Wednesday, 4 March, 15
App.StoryAdapter = DS.Adapter.extend({ findAll(store, type, id) { return $.get("/news"); }
}); App.StorySerializer = DS.Serializer.extend({ extractArray(store, type, payload) { var stories = []; $(payload).find("tr .title a").each( ... ); return stories; } }); Wednesday, 4 March, 15
FIXING THE URLS Wednesday, 4 March, 15
Wednesday, 4 March, 15
/ Wednesday, 4 March, 15
/ /stories/ Wednesday, 4 March, 15
/ /stories/ /stories/9132815/ Wednesday, 4 March, 15
/ /stories/ /stories/9132815/ /stories/9132815/COMMENTS/ Wednesday, 4 March, 15
“IDEAL” URLS /stories /stories?filter=latest /stories/9132815/comments /stories/9132815/comments?highlight=9133317 Hacker News URLS /news
/newest /item?id=9132815 /item?id=9133317 Wednesday, 4 March, 15
Ember ROUTER HACKER NEWS URLS Wednesday, 4 March, 15
Ember ROUTER ( ACTUAL APP STATES ) HACKER NEWS URLS
( SERIALIZED APP STATES ) Wednesday, 4 March, 15
Ember ROUTER ( ACTUAL APP STATES ) HACKER NEWS URLS
( SERIALIZED APP STATES ) Wednesday, 4 March, 15
History LOCATION /stories /stories?filter=latest /stories/9132815/comments /stories/9132815/comments?highlight=9133317 HASH LOCATION #/stories #/stories?filter=latest
#/stories/9132815/comments #/stories/9132815/comments?highlight=9133317 Wednesday, 4 March, 15
Ember.HistoryLocation Ember.HashLocation Wednesday, 4 March, 15
App.HackerNewsLocation = Ember.HistoryLocation.extend({ getURL: function() { if (this._super() === "/news")
{ return "/stories"; } else if (...) { ... } }, formatURL: function( logicalPath ) { if (logicalPath === "/stories") { return "/news"; } else if (...) { ... } } }); App.Router.reopen({ location: 'hacker-news' }); Wednesday, 4 March, 15
PREFERENCES Wednesday, 4 March, 15
Ember ROUTER <p>{{ localStorage.zomg }}</p> LOCAL STORAGE localStorage.getItem(“zomg”) Wednesday, 4
March, 15
LOCAL STORAGE localStorage.getItem(“key”); localStorage.setItem(“key”, value); $(window).on(“storage”, ...); EMBER.OBSERVABLE obj.get(“key”); obj.set(“key”,
value); obj.addObserver( ... ); Wednesday, 4 March, 15
App.LocalStorage = Ember.Object.extend({ init: function() { $(window).on("storage", Ember.run.bind(this, "_onStorageEvent") );
}, unknownProperty: function(key) { return localStorage.getItem(key); }, setUnknownProperty: function(key, value) { localStorage.setItem(key, value); return true; }, _onStorageEvent: function(e) { this.notifyPropertyChange(e.key); }, willDestroy: function() { $(window).off("storage"); } }); Wednesday, 4 March, 15
THE POSSIBILITIES Wednesday, 4 March, 15
HTML <div> <span> <img> Cocoa UIView UITextView UIImageView Wednesday, 4
March, 15
Wednesday, 4 March, 15
COCOA BARS! Wednesday, 4 March, 15
$ cd cocoabars $ git status # On branch master
# # Initial commit # nothing to commit (create/copy files and use "git add" to track) Wednesday, 4 March, 15
@chancancode Wednesday, 4 March, 15
Wednesday, 4 March, 15
Here is the URL you are looking for: https://github.com/chancancode/hn-reader Wednesday,
4 March, 15
A few awesome things didn’t make it to the slides.
I’ll be tweeting, stay tuned. Wednesday, 4 March, 15
I’d like to dedicate this talk to my favourite teacher
and life-mentor, Miss Shirley Ngai. Wednesday, 4 March, 15
Thank you EmberConf team for putting this together! Wednesday, 4
March, 15
And of course, thank you Ember contributors for making this
amazing framework. Wednesday, 4 March, 15
Huge thanks to those who beta tested my app and
tolerated the “dry” runs of my talk. Wednesday, 4 March, 15
And finally, thank YOU for sitting through my first-ever conference
talk and being awesome! Wednesday, 4 March, 15
One more thing. Wednesday, 4 March, 15
<canvas> bars Wednesday, 4 March, 15
Wednesday, 4 March, 15
(Yes, that’s it.) Wednesday, 4 March, 15
Wednesday, 4 March, 15