SlideShare uma empresa Scribd logo
1 de 205
Baixar para ler offline
Building a Single Page
App with Ember.js
…for fun and profit!
largest free entrepreneurial event of its kind in
North America
yay, sponsors!
Ben Limmer
blimmer
@l1m5
hello@benlimmer.com
ember.party
conceptual
Ron White
ronco
@ronco1337
live coding
$2
cash back
$5
cash back
$5
cash back
$10
cash back
$10
cash back
we need a website
ok - what does it do?
it’s simple, really
show rebates
it needs to
allow registration
allow account mgmt
provide cash out
explain how it works
show where it works
…
build a shopping list
be location aware
track all the things
how do we build it?
server-rendered?
ibotta.com
ibotta.com
ibotta.com
html, js, css
ibotta.com
*click*
html, js, css
ibotta.com
ibotta.com
client rendered?
(single page app)
ibotta.com
ibotta.com
ibotta.com
html, js, css
ibotta.com
*click*
ibotta.com
json
ibotta.com
*click*
ibotta.com
*click*
ibotta.com
ibotta.com
single page apps are not
always the best choice.
pre-render challenges
(seo, social share)
overkill for simple sites
some duplication
of backend data
requires (building)
an API
but you’re here
single page app frameworks
single page app frameworks
single page app frameworks
single page app frameworks
single page app frameworks
single page app frameworks
very
un-opinionated
very
opinionated
so why did we go with
Ember @ Ibotta?
¯_(ツ)_/¯
convention over
configuration
– Ruby on Rails Guides
“conventions will speed up development, keep
your code concise and readable and - most
important - these conventions allow you an easy
navigation inside your application.”
https://en.wikibooks.org/wiki/Ruby_on_Rails/Getting_Started/Convention_Over_Configuration* emphasis mine
structure of an ember app
app
├── components
├── controllers
├── helpers
├── models
├── routes
├── styles
└── templates
└── components
tests
├── helpers
├── integration
│ └── components
└── unit
who cares? it’s just a
framework…
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
knowledge in the head
vs.
knowledge in the world
adapted from concepts in Don Norman’s
The Design of Everyday Things
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by
many
used by
few
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by
few
used by
many
more knowledge
in the head
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by
few
used by
many
more knowledge
in the head
more knowledge
in the world
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by
few
used by
many
more knowledge
in the head
more knowledge
in the world
*Icons made Freepik from www.flaticon.com is licensed by CC BY 3.0
used by
few
used by
many
more knowledge
in the head
more knowledge
in the world
}how it
works
how it
works
how it
works
how it
works
?
}how it
works
}how it
works
best practices are
established
testing
routing data definition
validation i18n
builds deployment
dev tools
upgrade paths
“there’s an
add-on for that”
automated
testing
out-of-the-box support
w/ qunit and phantom
modern
language
features
out-of-the-box support
for ES6/ES2015++ with
Babel.js
✓Array comprehensions
✓Arrow functions
✓Async functions
✓Async generator functions
✓Classes
✓Class properties
✓Computed property names
✓Constants
✓Decorators
✓Default parameters
✓Destructuring
✓Exponentiation operator
✓For-of
✓Function bind
✓Generators
✓Generator comprehensions
✓Let scoping
✓Modules
✓Module export extensions
✓Object rest/spread
✓Property method assignment
✓Property name shorthand
✓Rest parameters
✓React
✓Spread
✓Template literals
✓Type annotations
✓Unicode regex
no more
var self = this;
design
frameworks
plug-and-play support for
the most popular design
frameworks and
preprocessors
i18n
ember i18n
您好
Здравствуйте!
hello
bonjour
hola
“there’s an
add-on for that”
“there’s (not) an
add-on for that”
ember add-on
thriving community
3000 members
(and growing)
400 members
(and growing)
Denver Devs
DenverDevs.org
meetup.com/
Ember-js-Denver
ember @ ibotta
0 to prod in two
months
> 2x traffic
internal ember apps
let’s build something.
…but first
initial questions?
let’s build something.
Our App
Our App
$ ember new bbs
demo
structure of our app
app
├── components
├── controllers
├── helpers
├── models
├── routes
├── styles
└── templates
└── components
tests
├── helpers
├── integration
│ └── components
└── unit
./app/templates/application.hbs
1 <h2 id="title">Welcome to Ember</h2>
2
3 {{outlet}}
Live reload demo here.

Hello Denver!
demo
$ ember install ember-cli-materialize
$ ember install ember-i18n
demo
I18n
1 <!-- ./app/templates/index.hbs -->
2 <div class="home-feature">
3 <div class="feature-content">
4 <h1>{{t 'index.headline'}}</h1>
5 <h3>{{t 'index.subTitle'}}</h3>
6 </div>
7 </div>
1 // ./app/locales/en/translations.js
2 export default {
3 'index': {
4 'headline': 'Frozen Bananas!',
5 'subTitle': 'Coming Soon'
6 }
7 };
I18n
3 <div class="feature-content">
4 <h1>{{t 'index.headline'}}</h1>
5 <h3>{{t 'index.subTitle'}}</h3>
6 </div>
I18n
1 <!-- ./app/templates/index.hbs -->
2 <div class="home-feature">
3 <div class="feature-content">
4 <h1>{{t 'index.headline'}}</h1>
5 <h3>{{t 'index.subTitle'}}</h3>
6 </div>
7 </div>
1 // ./app/locales/en/translations.js
2 export default {
3 'index': {
4 'headline': 'Frozen Bananas!',
5 'subTitle': 'Coming Soon'
6 }
7 };
I18n
1 // ./app/locales/en/translations.js
2 export default {
3 'index': {
4 'headline': 'Frozen Bananas!',
5 'subTitle': 'Coming Soon'
6 }
7 };
$ ember generate
acceptance-test index
./tests/acceptance/index-test.js
1 // ...
2
3 test('visiting /index', function(assert) {
4 assert.expect(3);
5 visit('/');
6
7 andThen(function() {
8 assert.equal(currentURL(), '/');
9 let headline = find('.home-feature h1');
10 assert.equal(headline.length, 1);
11 assert.equal(headline.text(), 'Frozen Bananas!');
12 });
13 }); Promise explainer Here?
./tests/acceptance/index-test.js
5 visit('/');
./tests/acceptance/index-test.js
1 // ...
2
3 test('visiting /index', function(assert) {
4 assert.expect(3);
5 visit('/');
6
7 andThen(function() {
8 assert.equal(currentURL(), '/');
9 let headline = find('.home-feature h1');
10 assert.equal(headline.length, 1);
11 assert.equal(headline.text(), 'Frozen Bananas!');
12 });
13 });
./tests/acceptance/index-test.js
7 andThen(function() {
8 assert.equal(currentURL(), '/');
9 let headline = find('.home-feature h1');
10 assert.equal(headline.length, 1);
11 assert.equal(headline.text(), 'Frozen Bananas!');
12 });
√ ok 1 PhantomJS 2.0 - Acceptance | index: visiting /index
Our App
Our App
$ ember generate route about
./app/router.js
1 import Ember from 'ember';
2 import config from './config/environment';
3
4 var Router = Ember.Router.extend({
5 location: config.locationType
6 });
7
8 Router.map(function() {
9 this.route('about');
10 });
11
12 export default Router;
./app/router.js
8 Router.map(function() {
9 this.route('about');
10 });
./app/templates/about.hbs
1 <div class="container">
2 {{#md-card
3 title=(t 'about.title')
4 class="teal"
5 titleClass="white-text"
6 bodyClass="white-text"
7 id="address-card"}}
8 {{#md-card-content class="white-text"}}
9 <p>{{t 'about.number'}}</p>
10 <p>{{t 'about.street'}}</p>
11 {{/md-card-content}}
12 {{/md-card}}
13 </div>
./app/templates/about.hbs
2 {{#md-card
3 title=(t 'about.title')
4 class="teal"
5 titleClass="white-text"
6 bodyClass="white-text"
7 id="address-card"}}
12 {{/md-card}}
./app/templates/about.hbs
1 <div class="container">
2 {{#md-card
3 title=(t 'about.title')
4 class="teal"
5 titleClass="white-text"
6 bodyClass="white-text"
7 id="address-card"}}
8 {{#md-card-content class="white-text"}}
9 <p>{{t 'about.number'}}</p>
10 <p>{{t 'about.street'}}</p>
11 {{/md-card-content}}
12 {{/md-card}}
13 </div>
./app/templates/about.hbs
8 {{#md-card-content class="white-text"}}
9 <p>{{t 'about.number'}}</p>
10 <p>{{t 'about.street'}}</p>
11 {{/md-card-content}}
./app/templates/index.hbs
1 <div class="home-feature">
2 <div class="feature-content">
3 <h1>{{t 'index.headline'}}</h1>
4 <h3>{{t 'index.subTitle'}}</h3>
5 <div class="about-link">
6 {{#link-to 'about'}}
7 <img src="/images/banana_grabber.png">
8 {{/link-to}}
9 </div>
10 </div>
11 </div>
./app/templates/index.hbs
5 <div class="about-link">
6 {{#link-to 'about'}}
7 <img src="/images/banana_grabber.png">
8 {{/link-to}}
9 </div>
demo
$ ember generate
acceptance-test about
./tests/acceptance/about-test.js
1 // ...
2
3 test('visiting /about from index', function(assert) {
4 visit('/');
5 click('.about-link img');
6
7 andThen(function() {
8 assert.equal(currentURL(), '/about');
9 });
10 });
√ ok 1 PhantomJS 2.0 -
Acceptance | about: visiting /about from index
$ ember generate
model company-address
./app/models/company-address.js
1 import DS from 'ember-data';
2
3 export default DS.Model.extend({
4 name: DS.attr('string'),
5 street1: DS.attr('string'),
6 street2: DS.attr('string'),
7 city: DS.attr('string'),
8 state: DS.attr('string'),
9 zip: DS.attr('string') //string not number
10 });
./app/models/company-address.js
4 name: DS.attr('string'),
5 street1: DS.attr('string'),
6 street2: DS.attr('string'),
7 city: DS.attr('string'),
8 state: DS.attr('string'),
9 zip: DS.attr('string') //string not number
./app/routes/about.js
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4 model() {
5 return this.get('store').findAll('company-address');
6 }
7 });
Promises
Objects not Callbacks
Complete or Not
Chainable
Traditional async
1 asyncCall1(function() {
2 asyncCall2(function() {
3 asyncCall3(function() {
4 asyncCall4(function() {
5 asyncCall5(function() {
6 finalCall();
7 });
8 });
9 });
10 });
11 });
Chained Promises
1 asyncCall1()
2 .then(asyncCall2)
3 .then(asyncCall3)
4 .then(asyncCall4)
5 .then(asyncCall5)
6 .then(finalCall);
Chained Promises
1 asyncCall1()
2 .then(asyncCall2)
3 .then(asyncCall3)
4 .then(asyncCall4)
5 .then(asyncCall5)
6 .then(finalCall)
7 .catch(errorHandler);
Deferred Interest
./app/routes/about.js
4 model() {
5 return this.get('store').findAll('company-address');
6 }
.then(the-template)
./app/templates/about.hbs
1 <div class="container">
2 {{#md-card
3 title=model.lastObject.name
4 class="teal"
5 titleClass="white-text"
6 bodyClass="white-text"
7 id="address-card"}}
8 {{#md-card-content class="white-text"}}
9 <p>{{model.lastObject.street1}}</p>
10 <p>{{model.lastObject.street2}}</p>
11 <p>
12 {{model.lastObject.city}}, {{model.lastObject.state}}
13 {{model.lastObject.zip}}
14 </p>
15 {{/md-card-content}}
16 {{/md-card}}
17 </div>
Demo, show error page
./app/templates/about.hbs
9 <p>{{model.lastObject.street1}}</p>
10 <p>{{model.lastObject.street2}}</p>
11 <p>
12 {{model.lastObject.city}}, {{model.lastObject.state}}
13 {{model.lastObject.zip}}
14 </p>
Demo, show error page
demo
./app/templates/error.hbs
1 <div class="error-page">
2 <h1>Ooops!</h1>
3 {{shrug-guy}}
4 </div>
./app/templates/error.hbs
3 {{shrug-guy}}
./app/templates/error.hbs
¯_(ツ)_/¯
Gob
Server Engineer
$ ember install ember-cli-mirage
$ ember generate
fixture company-addresses
./app/mirage/fixtures/company-addresses.js
1 export default [
2 {
3 id: 1,
4 name: 'Bluth's Banana Stand',
5 street1: 'In a Van',
6 street2: 'Down by the river',
7 city: 'Denver',
8 state: 'CO',
9 zip: 80202
10 }
11 ];
./app/mirage/config.js
1 export default function() {
2
3 this.get('/companyAddresses', 'company-addresses');
4
5 }
./app/mirage/config.js
3 this.get('/companyAddresses', 'company-addresses');
demo
./app/mirage/config.js
1 export default function() {
2 this.timing = 2000;
3
4 this.get('/companyAddresses', 'company-addresses');
5
6 }
./app/mirage/config.js
2 this.timing = 2000;
./app/templates/loading.hbs
1 <div class="loading-page">
2 {{md-loader}}
3 </div>
./app/templates/loading.hbs
2 {{md-loader}}
demo
Our App
Our App
$ ember generate component
subscribe-form
Components Are Reusable
Components Are Reusable
Our App
./app/templates/index.hbs
1 <div class="home-feature">
2 <div class="feature-content row">
3 <div class="col m6">
4 <h1>{{t 'index.headline'}}</h1>
5 <h3>{{t 'index.subTitle'}}</h3>
6 <div class="about-link">
7 {{#link-to 'about'}}
8 <img src="/images/banana_grabber.png">
9 {{/link-to}}
10 </div>
11 </div>
12 <div class="subscribe-container col m6">
13 {{subscribe-form model=model}}
14 </div>
15 </div>
16 </div>
./app/templates/index.hbs
13 {{subscribe-form model=model}}
$ ember generate
model email-subscription
./app/models/email-subscription.js
1 import DS from 'ember-data';
2
3 export default DS.Model.extend({
4 email: DS.attr('string'),
5 marketing: DS.attr('boolean', {
6 defaultValue: true
7 })
8 });
./app/models/email-subscription.js
5 marketing: DS.attr('boolean', {
6 defaultValue: true
7 })
./app/routes/index.js
1 import Ember from 'ember';
2
3 export default Ember.Route.extend({
4 model() {
5 return this.get('store').createRecord('email-subscription');
6 }
7 });
./app/routes/index.js
5 return this.get(‘store')
.createRecord('email-subscription');
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}}
2 {{#if saved}}
3 {{#md-card-content}}
4 {{t 'subscribe.successMessage' email=model.email}}
5 {{/md-card-content}}
6 {{else}}
7 {{#md-card-content}}
8 {{md-input value=model.email label=(t 'subscribe.email.label')
9 type='email' validate=true}}
10 {{md-check checked=model.marketing
11 name=(t 'subscribe.marketing.label')}}
12 {{#if saving}}
13 {{md-loader}}
14 {{/if}}
15 {{/md-card-content}}
16 {{#md-card-action}}
17 <button {{action 'subscribe'}}>
18 {{t 'subscribe.submit'}}
19 </button>
20 {{/md-card-action}}
21 {{/if}}
22 {{/md-card}}
./app/templates/components/subscribe-form.hbs
8 {{md-input value=model.email
label=(t subscribe.email.label')
9 type='email' validate=true}}
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}}
2 {{#if saved}}
3 {{#md-card-content}}
4 {{t 'subscribe.successMessage' email=model.email}}
5 {{/md-card-content}}
6 {{else}}
7 {{#md-card-content}}
8 {{md-input value=model.email label=(t 'subscribe.email.label')
9 type='email' validate=true}}
10 {{md-check checked=model.marketing
11 name=(t 'subscribe.marketing.label')}}
12 {{#if saving}}
13 {{md-loader}}
14 {{/if}}
15 {{/md-card-content}}
16 {{#md-card-action}}
17 <button {{action 'subscribe'}}>
18 {{t 'subscribe.submit'}}
19 </button>
20 {{/md-card-action}}
21 {{/if}}
22 {{/md-card}}
./app/templates/components/subscribe-form.hbs
10 {{md-check checked=model.marketing
11 name=(t 'subscribe.marketing.label')}}
./app/templates/components/subscribe-form.hbs
1 {{#md-card title=title}}
2 {{#if saved}}
3 {{#md-card-content}}
4 {{t 'subscribe.successMessage' email=model.email}}
5 {{/md-card-content}}
6 {{else}}
7 {{#md-card-content}}
8 {{md-input value=model.email label=(t 'subscribe.email.label')
9 type='email' validate=true}}
10 {{md-check checked=model.marketing
11 name=(t 'subscribe.marketing.label')}}
12 {{#if saving}}
13 {{md-loader}}
14 {{/if}}
15 {{/md-card-content}}
16 {{#md-card-action}}
17 <button {{action 'subscribe'}}>
18 {{t 'subscribe.submit'}}
19 </button>
20 {{/md-card-action}}
21 {{/if}}
22 {{/md-card}}
./app/templates/components/subscribe-form.hbs
17 <button {{action 'subscribe'}}>
18 {{t 'subscribe.submit'}}
19 </button>
./app/components/subscribe-form.js
1 import Ember from 'ember';
2
3 export default Ember.Component.extend({
4 i18n: Ember.inject.service('i18n'),
5 title: Ember.computed('saved', function() {
6 if (this.get('saved')) {
7 return this.get('i18n').t('subscribe.successHeader');
8 } else {
9 return this.get('i18n').t('subscribe.header');
10 }
11 }),
12 saved: false,
13 actions: {
14 subscribe() {
15 this.set('saving', true);
16 this.get('model').save().then(() => {
17 this.set('saving', false);
18 this.set('saved', true);
19 }, () => {
20 //error handling here
21 });
22 }
23 }
24 });
./app/components/subscribe-form.js
5 title: Ember.computed('saved', function() {
6 if (this.get('saved')) {
7 return this.get('i18n').t('subscribe.successHeader');
8 } else {
9 return this.get('i18n').t('subscribe.header');
10 }
11 }),
./app/components/subscribe-form.js
1 import Ember from 'ember';
2
3 export default Ember.Component.extend({
4 i18n: Ember.inject.service('i18n'),
5 title: Ember.computed('saved', function() {
6 if (this.get('saved')) {
7 return this.get('i18n').t('subscribe.successHeader');
8 } else {
9 return this.get('i18n').t('subscribe.header');
10 }
11 }),
12 saved: false,
13 actions: {
14 subscribe() {
15 this.set('saving', true);
16 this.get('model').save().then(() => {
17 this.set('saving', false);
18 this.set('saved', true);
19 }, () => {
20 //error handling here
21 });
22 }
23 }
24 });
./app/components/subscribe-form.js
13 actions: {
14 subscribe() {
15 this.set('saving', true);
16 this.get('model').save().then(() => {
17 this.set('saving', false);
18 this.set('saved', true);
19 }, () => {
20 //error handling here
21 });
22 }
23 }
./app/mirage/config.js
1 export default function() {
2 this.timing = 2000;
3
4 this.get('/companyAddresses', 'company-addresses');
5
6 this.post('/emailSubscriptions',
7 'email-subscriptions');
8 }
./app/mirage/config.js
6 this.post('/emailSubscriptions',
7 'email-subscriptions');
demo
./tests/integration/components/subscribe-form-test.js
1 test('it renders', function(assert) {
2 assert.expect(3);
3
4 this.render(hbs`{{subscribe-form}}`);
5
6 assert.equal(
7 this.$('.card-title').text().trim(),
8 'Subscribe for updates on the stand.'
9 );
10
11 assert.equal(
12 this.$('.input-field label').text().trim(),
13 'Please enter your email address.'
14 );
15
16 assert.equal(
17 this.$('.materialize-checkbox label').text().trim(),
18 'Yes I would like to receive marketing material from Bluth sponsors.
19 '
20 );
21
22 });
./tests/acceptance/index-test.hbs
1 test('subscribe for updates', function(assert) {
2 visit('/');
3
4 fillIn(
5 '.subscribe-container .input-field input',
6 'veep@whitehouse.gov'
7 );
8 click('.card-action button');
9 andThen(() => {
10 // stays on index
11 assert.equal(currentURL(), '/');
12
13 assert.equal(
14 find('.subscribe-container .card-title').text().trim(),
15 'Thanks for signing up.'
16 );
17 assert.equal(
18 find('.card p').text().trim(),
19 'We'll send all of our updates to veep@whitehouse.gov.'
20 );
21 });
22
23 });
test demo
what we just built
• https://github.com/Ibotta/dsw-2015-ember-demo
ibotta.com/careers
Thanks!

Mais conteúdo relacionado

Mais procurados

Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien Lecomte
 
Nahlédněte za oponu VersionPressu
Nahlédněte za oponu VersionPressuNahlédněte za oponu VersionPressu
Nahlédněte za oponu VersionPressuJan Voracek
 
Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014Jan Jongboom
 
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...Juliano Martins
 
Essential open source tools for serverless developers
Essential open source tools for serverless developersEssential open source tools for serverless developers
Essential open source tools for serverless developersYan Cui
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsYan Cui
 
BDD - Writing better scenario
BDD - Writing better scenarioBDD - Writing better scenario
BDD - Writing better scenarioArnauld Loyer
 
Behat - Drupal South 2018
Behat  - Drupal South 2018Behat  - Drupal South 2018
Behat - Drupal South 2018Berend de Boer
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsRyan Weaver
 
DPC 2007 My First Mashup (Cal Evans)
DPC 2007 My First Mashup (Cal Evans)DPC 2007 My First Mashup (Cal Evans)
DPC 2007 My First Mashup (Cal Evans)dpc
 
III - Better angularjs
III - Better angularjsIII - Better angularjs
III - Better angularjsWebF
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
Untangling the web9
Untangling the web9Untangling the web9
Untangling the web9Derek Jacoby
 

Mais procurados (20)

EPiServer Web Parts
EPiServer Web PartsEPiServer Web Parts
EPiServer Web Parts
 
SocketStream
SocketStreamSocketStream
SocketStream
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
WordPress and Ajax
WordPress and AjaxWordPress and Ajax
WordPress and Ajax
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
Nahlédněte za oponu VersionPressu
Nahlédněte za oponu VersionPressuNahlédněte za oponu VersionPressu
Nahlédněte za oponu VersionPressu
 
Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...
Desenvolvendo uma aplicação híbrida para Android e IOs utilizando Ionic, aces...
 
Essential open source tools for serverless developers
Essential open source tools for serverless developersEssential open source tools for serverless developers
Essential open source tools for serverless developers
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 steps
 
BDD - Writing better scenario
BDD - Writing better scenarioBDD - Writing better scenario
BDD - Writing better scenario
 
Behat - Drupal South 2018
Behat  - Drupal South 2018Behat  - Drupal South 2018
Behat - Drupal South 2018
 
Namshi in 2014: let's rock!
Namshi in 2014: let's rock!Namshi in 2014: let's rock!
Namshi in 2014: let's rock!
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
 
DPC 2007 My First Mashup (Cal Evans)
DPC 2007 My First Mashup (Cal Evans)DPC 2007 My First Mashup (Cal Evans)
DPC 2007 My First Mashup (Cal Evans)
 
III - Better angularjs
III - Better angularjsIII - Better angularjs
III - Better angularjs
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
How cgi scripting works
How cgi scripting worksHow cgi scripting works
How cgi scripting works
 
Untangling the web9
Untangling the web9Untangling the web9
Untangling the web9
 

Destaque

Ember Conf 2016: Building Mobile Apps with Ember
Ember Conf 2016: Building Mobile Apps with EmberEmber Conf 2016: Building Mobile Apps with Ember
Ember Conf 2016: Building Mobile Apps with EmberAlex Blom
 
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Fwdays
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
Fun with Ember 2.x Features
Fun with Ember 2.x FeaturesFun with Ember 2.x Features
Fun with Ember 2.x FeaturesBen Limmer
 
Single Page Apps with Drupal 8
Single Page Apps with Drupal 8Single Page Apps with Drupal 8
Single Page Apps with Drupal 8Chris Tankersley
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.jsJay Phelps
 
An introduction to Ember.js
An introduction to Ember.jsAn introduction to Ember.js
An introduction to Ember.jscodeofficer
 

Destaque (7)

Ember Conf 2016: Building Mobile Apps with Ember
Ember Conf 2016: Building Mobile Apps with EmberEmber Conf 2016: Building Mobile Apps with Ember
Ember Conf 2016: Building Mobile Apps with Ember
 
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
Fun with Ember 2.x Features
Fun with Ember 2.x FeaturesFun with Ember 2.x Features
Fun with Ember 2.x Features
 
Single Page Apps with Drupal 8
Single Page Apps with Drupal 8Single Page Apps with Drupal 8
Single Page Apps with Drupal 8
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.js
 
An introduction to Ember.js
An introduction to Ember.jsAn introduction to Ember.js
An introduction to Ember.js
 

Semelhante a Building a Single Page Application using Ember.js ... for fun and profit

Intro To Django
Intro To DjangoIntro To Django
Intro To DjangoUdi Bauman
 
The Dojo Build System
The Dojo Build SystemThe Dojo Build System
The Dojo Build Systemklipstein
 
Modular Web Applications With Netzke
Modular Web Applications With NetzkeModular Web Applications With Netzke
Modular Web Applications With Netzkenetzke
 
Use Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile AppsUse Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile AppsNathan Smith
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web DesignChristopher Schmitt
 
5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniternicdev
 
Moving from Web 1.0 to Web 2.0
Moving from Web 1.0 to Web 2.0Moving from Web 1.0 to Web 2.0
Moving from Web 1.0 to Web 2.0Estelle Weyl
 
The Enterprise Architecture You Always Wanted
The Enterprise Architecture You Always WantedThe Enterprise Architecture You Always Wanted
The Enterprise Architecture You Always WantedThoughtworks
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Innomatic Platform
 
Desenvolvimento Mobile Híbrido
Desenvolvimento Mobile HíbridoDesenvolvimento Mobile Híbrido
Desenvolvimento Mobile HíbridoJuliano Martins
 
20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdevFrank Rousseau
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
IBM Lotus Notes Domino XPages and XPages for Mobile
IBM Lotus Notes Domino XPages and XPages for MobileIBM Lotus Notes Domino XPages and XPages for Mobile
IBM Lotus Notes Domino XPages and XPages for MobileChris Toohey
 
React Native Workshop - React Alicante
React Native Workshop - React AlicanteReact Native Workshop - React Alicante
React Native Workshop - React AlicanteIgnacio Martín
 
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...Codemotion
 

Semelhante a Building a Single Page Application using Ember.js ... for fun and profit (20)

Intro To Django
Intro To DjangoIntro To Django
Intro To Django
 
The Dojo Build System
The Dojo Build SystemThe Dojo Build System
The Dojo Build System
 
Modular Web Applications With Netzke
Modular Web Applications With NetzkeModular Web Applications With Netzke
Modular Web Applications With Netzke
 
Use Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile AppsUse Web Skills To Build Mobile Apps
Use Web Skills To Build Mobile Apps
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design
 
5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter5 Reasons To Love CodeIgniter
5 Reasons To Love CodeIgniter
 
Adobe & HTML5
Adobe & HTML5Adobe & HTML5
Adobe & HTML5
 
Nodejs.meetup
Nodejs.meetupNodejs.meetup
Nodejs.meetup
 
Moving from Web 1.0 to Web 2.0
Moving from Web 1.0 to Web 2.0Moving from Web 1.0 to Web 2.0
Moving from Web 1.0 to Web 2.0
 
Road to Rails
Road to RailsRoad to Rails
Road to Rails
 
The Enterprise Architecture You Always Wanted
The Enterprise Architecture You Always WantedThe Enterprise Architecture You Always Wanted
The Enterprise Architecture You Always Wanted
 
SearchMonkey
SearchMonkeySearchMonkey
SearchMonkey
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
 
Desenvolvimento Mobile Híbrido
Desenvolvimento Mobile HíbridoDesenvolvimento Mobile Híbrido
Desenvolvimento Mobile Híbrido
 
20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev
 
Taking your Web App for a walk
Taking your Web App for a walkTaking your Web App for a walk
Taking your Web App for a walk
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
IBM Lotus Notes Domino XPages and XPages for Mobile
IBM Lotus Notes Domino XPages and XPages for MobileIBM Lotus Notes Domino XPages and XPages for Mobile
IBM Lotus Notes Domino XPages and XPages for Mobile
 
React Native Workshop - React Alicante
React Native Workshop - React AlicanteReact Native Workshop - React Alicante
React Native Workshop - React Alicante
 
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...
Danny Banks - Building consistent Cross-Platform interfaces - Codemotion Amst...
 

Mais de Ben Limmer

Tips & Tricks for Being a Successful Tech Lead
Tips & Tricks for Being a Successful Tech LeadTips & Tricks for Being a Successful Tech Lead
Tips & Tricks for Being a Successful Tech LeadBen Limmer
 
1-Up Your Git Skills
1-Up Your Git Skills1-Up Your Git Skills
1-Up Your Git SkillsBen Limmer
 
Maximize your output (sans productivity shame)
Maximize your output (sans productivity shame)Maximize your output (sans productivity shame)
Maximize your output (sans productivity shame)Ben Limmer
 
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)Ben Limmer
 
Upgrading Ember.js Apps
Upgrading Ember.js AppsUpgrading Ember.js Apps
Upgrading Ember.js AppsBen Limmer
 
Automated Testing in EmberJS
Automated Testing in EmberJSAutomated Testing in EmberJS
Automated Testing in EmberJSBen Limmer
 
Deploying a Location-Aware Ember Application
Deploying a Location-Aware Ember ApplicationDeploying a Location-Aware Ember Application
Deploying a Location-Aware Ember ApplicationBen Limmer
 

Mais de Ben Limmer (7)

Tips & Tricks for Being a Successful Tech Lead
Tips & Tricks for Being a Successful Tech LeadTips & Tricks for Being a Successful Tech Lead
Tips & Tricks for Being a Successful Tech Lead
 
1-Up Your Git Skills
1-Up Your Git Skills1-Up Your Git Skills
1-Up Your Git Skills
 
Maximize your output (sans productivity shame)
Maximize your output (sans productivity shame)Maximize your output (sans productivity shame)
Maximize your output (sans productivity shame)
 
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)
[OLD] Understanding Github PR Merge Options (1up-ing your git skills part 2)
 
Upgrading Ember.js Apps
Upgrading Ember.js AppsUpgrading Ember.js Apps
Upgrading Ember.js Apps
 
Automated Testing in EmberJS
Automated Testing in EmberJSAutomated Testing in EmberJS
Automated Testing in EmberJS
 
Deploying a Location-Aware Ember Application
Deploying a Location-Aware Ember ApplicationDeploying a Location-Aware Ember Application
Deploying a Location-Aware Ember Application
 

Último

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 

Último (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 

Building a Single Page Application using Ember.js ... for fun and profit