Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
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
Transcript
82 slides
@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
More Decks by Godfrey Chan
See All by Godfrey Chan
Virtual EmberConf 2022: Platform State of the Union
chancancode
0
330
Virtual EmberConf 2021: Platform State of the Union
chancancode
0
250
Virtual EmberConf 2020: Platform State of the Union
chancancode
1
400
Thinking in TypeScript
chancancode
0
330
The Lifecycle of a Rails Request
chancancode
3
15k
Dropping Down To The Metal™ (2018)
chancancode
0
180
Using Skylight to Solve Real-World Performance Problems
chancancode
1
490
Prying Open The Black Box (EmberConf 2018)
chancancode
0
460
Bending The Curve: Putting Rust in Ruby with Helix
chancancode
2
2.9k
Other Decks in Programming
See All in Programming
仕様駆動開発入門 (何を作るかを先に決めて渡す) | 目指せ Kiro マスター 05
inariku
PRO
2
150
社内AIエージェント「Askワンバン」における コストチューニングの取り組み
t0yohei
0
170
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.7k
高橋メソッドでCVE解説シリーズ 〜CVE-2026-112816〜
hakkadaikon
0
260
エージェントを使い続けるためのメタワーク / Meta-work for keeping using the agent
rkaga
6
2.3k
Next.js: The final boss of Web Performance
guaca
0
400
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
420
Secure Your Coding Agent Like It’s Malware (v1.5) 🇬🇧 @Code.talks 2026
richargh
0
150
느린 네트워크와 저사양 디바이스 사용자를 위한 웹뷰 로딩 시간 개선기
kmkim
1
240
[Kotlin Fest 2026] eBPF Tracing for Kotlin
takehaya
0
120
複数ドメインを一つのアプリに統合するFlutterの設計と運用_FlutterKaigi2026登壇資料(須永高弘)
takahirosunaga
0
180
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
5
860
Featured
See All Featured
Abbi's Birthday
coloredviolet
5
11k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Navigating Team Friction
lara
192
16k
Test your architecture with Archunit
thirion
2
2.5k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
460
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
350
Rebuilding a faster, lazier Slack
samanthasiow
85
9.8k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
2
3.9k
GitHub's CSS Performance
jonrohan
1033
470k