On Github jheth / introduction-to-embercli
Joe Heth
@jheth
Powered By Broccoli (Beta)
Requires NodeJS
Ember CLI
npm install -g ember-cli
Bower
npm install -g bower
PhantomJS
npm install -g phantomjsBower - Package Manager for front-end dependencies up to date. PhantomJS used by default for integration testing. brew install node npm install -g grunt-cli
ember new blog
version: 0.1.2 installing create .bowerrc create .editorconfig create .ember-cli create .jshintrc create .travis.yml create Brocfile.js create README.md create app/app.js create app/components/.gitkeep create app/controllers/.gitkeep create app/helpers/.gitkeep create app/index.html create app/models/.gitkeep create app/router.js create app/routes/.gitkeep create app/styles/.gitkeep create app/styles/app.css create app/templates/.gitkeep create app/templates/application.hbs create app/templates/components/.gitkeep create app/views/.gitkeep create bower.json create config/environment.js create .gitignore create package.json create public/.gitkeep create public/crossdomain.xml create public/robots.txt create testem.json create tests/.jshintrc create tests/helpers/resolver.js create tests/helpers/start-app.js create tests/index.html create tests/test-helper.js create tests/unit/.gitkeep create vendor/.gitkeep Installed packages for tooling via npm. Installed browser packages via Bower. Successfully initialized git.Show Brocfile.js, bower.json, package.json, testem.json
cd blog ember server
version: 0.1.2 Livereload server on port 35729 Serving on http://0.0.0.0:4200/ Build successful - 372ms. Slowest Trees | Total -------------------------------+---------------- Concat | 96ms ES3SafeFilter | 36ms ES6Concatenator | 33ms JSHint - App | 31ms CustomStaticCompiler | 20ms TreeMerger (appAndDependencies) | 19msNode's Express Server, running on port 4200 LiveReload Broccoli build output
jheth@macbook: ~/blog$ ember generate route posts
// app/routes/posts.js import Ember from 'ember'; export default Ember.Route.extend({ model: function() { return this.store.find('post'); } });
jheth@macbook: ~/blog$ ember generate route post
// app/routes/post.js import Ember from 'ember'; export default Ember.Route.extend({ model: function(params) { return this.store.find('post', params.post_id); } });
// app/router.js Router.map(function() { this.route('posts'); this.route('post', { path: '/post/:post_id'}); });
jheth@macbook: ~/blog$ ember generate model post
// app/models/post.js import DS from 'ember-data'; var Post = DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), author: DS.attr('string'), createdAt: DS.attr('date'), isPublished: DS.attr('boolean') }); Post.reopenClass({ FIXTURES: [ { id: 1, title: 'Title A', body: 'Body A', author: 'Joe', createdAt: '2014-10-27T11:45:13', isPublished: false }, { id: 2, title: 'Title B', body: 'Body B', author: 'Paul', createdAt: '2014-10-27T12:15:00', isPublished: false } ] }); export default Post;
ember generate adapter post version: 0.1.2 installing create app/adapters/post.js installing create tests/unit/adapters/post-test.js
// app/adapters/post.js import DS from 'ember-data'; export default DS.FixtureAdapter.extend({ });
jheth@macbook: ~/blog$ ember generate components blog-post version: 0.1.2 installing create app/components/blog-post.js create app/templates/components/blog-post.hbs installing create tests/unit/components/blog-post-test.js
<div class="post"> <h1>{{post.title}}</h1> <p>{{post.body}}</p> </div>
// app/templates/application.hbs {{link-to 'Posts' 'posts'}}
// app/templates/post.hbs {{blog-post post=model}} {{outlet}}
// app/templates/posts.hbs <h1>My Blog ({{controller.length}})</h1> {{#each}} <h1>{{#link-to 'post' this }}{{title}}{{/link-to}}</h1> Created by {{author}} on {{createdAt}} {{#if isPublished}} <strong>PUBLISHED</strong> {{/if}} <hr> {{/each}}Delete Post
export default Ember.Component.extend({ isEditing: false, actions: { edit: function() { this.set('isEditing', true); }, save: function() { this.set('isEditing', false); }, publish: function() { this.set('post.isPublished', true); }, unpublish: function() { this.set('post.isPublished', false); } } });
<div class="post"> {{#if isEditing}} <h1>{{input type='text' value=post.title}}</h1> {{textarea value=post.body}} <br> <button {{action 'save'}}>Save</button> {{else}} <h1>{{post.title}}</h1> {{post.body}} <br> <button {{action 'edit'}}>Edit</button> {{#if post.isPublished}} <button {{action 'unpublish'}}>Unpublish</button> {{else}} <button {{action 'publish'}}>Publish</button> {{/if}} {{/if}} </div>
jheth@macbook: ~/blog$ ember generate controllers posts --type=array
import Ember from 'ember'; export default Ember.ArrayController.extend({ actions: { createPost: function() { this.store.createRecord('post', { id: Math.floor((Math.random() * 100) + 1), title: this.get('title'), body: this.get('body'), author: this.get('author'), createdAt: new Date().toISOString(), isPublished: false }); this.set('title', ''); this.set('body', ''); this.set('author', ''); }, deletePost: function(post) { post.destroyRecord(); } } });
jheth@macbook: ~/blog (master) $ ember test version: 0.1.2 Built project successfully. Stored in "/Users/jheth/Documents/Development/blog/tmp/class-tests_dist-OJ6ax2Eb.tmp". ok 1 PhantomJS 1.9 - JSHint - adapters: adapters/post.js should pass jshint ok 2 PhantomJS 1.9 - JSHint - .: app.js should pass jshint ok 3 PhantomJS 1.9 - JSHint - blog/tests/helpers: blog/tests/helpers/resolver.js should pass jshint ok 4 PhantomJS 1.9 - JSHint - blog/tests/helpers: blog/tests/helpers/start-app.js should pass jshint ok 5 PhantomJS 1.9 - JSHint - blog/tests: blog/tests/test-helper.js should pass jshint ok 6 PhantomJS 1.9 - JSHint - blog/tests/unit/adapters: blog/tests/unit/adapters/post-test.js should pass jshint ok 7 PhantomJS 1.9 - JSHint - blog/tests/unit/components: blog/tests/unit/components/blog-post-test.js should pass jshint ok 8 PhantomJS 1.9 - JSHint - blog/tests/unit/models: blog/tests/unit/models/post-test.js should pass jshint ok 9 PhantomJS 1.9 - JSHint - blog/tests/unit/routes: blog/tests/unit/routes/post-test.js should pass jshint ok 10 PhantomJS 1.9 - JSHint - blog/tests/unit/routes: blog/tests/unit/routes/posts-test.js should pass jshint ok 11 PhantomJS 1.9 - JSHint - components: components/blog-post.js should pass jshint ok 12 PhantomJS 1.9 - JSHint - models: models/post.js should pass jshint ok 13 PhantomJS 1.9 - JSHint - .: router.js should pass jshint ok 14 PhantomJS 1.9 - JSHint - routes: routes/post.js should pass jshint ok 15 PhantomJS 1.9 - JSHint - routes: routes/posts.js should pass jshint ok 16 PhantomJS 1.9 - PostAdapter: it exists ok 17 PhantomJS 1.9 - BlogPostComponent: it renders ok 18 PhantomJS 1.9 - Post: it exists ok 19 PhantomJS 1.9 - PostRoute: it exists ok 20 PhantomJS 1.9 - PostsRoute: it exists 1..20 # tests 20 # pass 20 # fail 0 # ok