Skip to content

Instantly share code, notes, and snippets.

@dreikanter
Last active December 11, 2023 05:01
Show Gist options
  • Save dreikanter/8b1e1cf05534febd9e00 to your computer and use it in GitHub Desktop.
Save dreikanter/8b1e1cf05534febd9e00 to your computer and use it in GitHub Desktop.
Ember.js Cheat Sheet

Core concepts

Model

  • An object that stores data (data persistance layer abstraction).
  • Templates transforms models into HTML.
  • Same thing as Rails model.

Template

  • Templates are written in Handlebars.
  • Has a name (file name or data-template-name attribute value of <script> element).
  • Backed by a model and auto-updates following model changes.
  • Can retrieve properties from Model and Controller.
  • Can nest one another template with {{outlet}} expression.
  • Uses text/x-handlebars type when defined in <script> blocks.
  • Unnamed script block will be treated as application (root) template.
<script type="text/x-handlebars">
  <div>
    {{outlet}}
  </div>
</script>
  • By default Ember will attach application template to the document's body element.
  • Root element could be changed during app creation:
App = Ember.Application.create({
  rootElement: '#app'
});
  • There are partial templates that can be included with render Handlebars expression.

Router

  • Router recognizes URL, and passes it to a Route object.
  • Translates URL into nested templates.
  • Keep browser address line updated.
App.Router.map(function() {
  this.resource('tasks', function() {
      this.route('task', { path: '/:task_id' });
  });

  this.route('user');
  this.route('project', { path: '/about' });
});

Route

  • Route sets up a Controller and supplies it with a Model.
  • Tells model which template to show.
  • Each route has controller and template with the same name.
  • Routes can implement hooks.
  • model hook can specify what model will be represented to the template by controller.
App.FavoritesRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('project');
  }
});
  • Using Ember Data is not mandatory. Model could be a plain JSON object:
App.UserRoute = Ember.Route.extend({
  model: function(params) {
    return {
      first_name: "Eric",
      last_name : "Sipple"
    };
  }
});

View

  • Views are for Creating reusable components and Setting up logic to handle events.
  • Can be used to handle browser events, and send the result to controller:
App.ProfilePhotoView = Ember.View.extend({
  click: function(evt) {
    this.get('controller').send('expandProfilePhoto');
  }
});

App.UserController = Ember.ObjectController.extend({
  actions: {
    expandProfilePhoto: function() {
      // Get the expanded picture and display it
    }
  }
});

Controller

  • Controller provides Model data to the Template.
  • Can be used to process Model data for the Template (calculated properties).
App.UserController = Ember.ObjectController.extend({
  fullName: function() {
    return this.get("first_name") + " " + this.get("last_name");
  }
});
  • May contain property and observer declarations (attention to get/set calls). Controller property monitors enumerated values and evaluate associated function. Observer executes their action respectively:
App.NumberController = Ember.ObjectController.extend({
  number: 1,
  timesTwo: function() {
    return Number(this.get('number')) * 2;
  }.property('number'),
  fullName: function() {
    // Calculate some value
    return this.get("first_name") + " " + this.get("last_name");
  }.property('first_name', 'last_name'),
  nameChanged: function() {
    // Execute some action
    console.log("New name! New name!");
  }.observes('first_name', 'last_name')
});
  • Example above will make this template alive:
{{input type="text" value=number size="50"}} x2 = {{timesTwo}}

Component

  • Reusable UI element.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta content='IE=Edge,chrome=1' http-equiv='X-UA-Compatible'>
<meta content='width=device-width, initial-scale=1.0' name='viewport'>
<title>Example Angular App</title>
<link rel="stylesheet" media="all" href="/assets/bootstrap_and_overrides.css?body=1" />
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico" />
<script src="/assets/jquery/jquery.js?body=1"></script>
<script src="/assets/jquery.js?body=1"></script>
<script src="/assets/jquery.ui.touch-punch.js?body=1"></script>
<script src="/assets/handlebars.js?body=1"></script>
<script src="/assets/ember.js?body=1"></script>
<script src="/assets/ember-data.js?body=1"></script>
</head>
<body>
<script type="text/x-handlebars">
<h1>{{appName}}</h1>
<h2>{{title}}</h2>
</script>
<script>
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('title', "Hello world!");
}
});
App.ApplicationController = Ember.Controller.extend({
appName: 'My First Example'
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta content='IE=Edge,chrome=1' http-equiv='X-UA-Compatible'>
<meta content='width=device-width, initial-scale=1.0' name='viewport'>
<title>Example Angular App</title>
<link rel="stylesheet" media="all" href="/assets/bootstrap_and_overrides.css?body=1" />
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico" />
<script src="/assets/jquery/jquery.js?body=1"></script>
<script src="/assets/jquery.js?body=1"></script>
<script src="/assets/jquery.ui.touch-punch.js?body=1"></script>
<script src="/assets/handlebars.js?body=1"></script>
<script src="/assets/ember.js?body=1"></script>
<script src="/assets/ember-data.js?body=1"></script>
</head>
<style>
body {
padding: 20px;
}
</style>
<body>
<script type="text/x-handlebars">
<h1>{{appName}}</h1>
<h2>{{title}}</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="projects_list">
<ul>
{{#each item in model}}
<li>{{#link-to 'project' item.id}}{{item.title}}{{/link-to}}</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="list_item">
<li>{{#link-to 'project' item.id}}{{item.title}}{{/link-to}}</li>
</script>
<script type="text/x-handlebars" data-template-name="project">
<dl>
<dt>Title:</dt>
<dd>{{model.title}}</dd>
<dt>ID:</dt>
<dd>{{model.id}}</dd>
</dl>
</script>
<script>
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('title', "Hello world!");
}
});
App.ApplicationController = Ember.Controller.extend({
appName: 'My First Example'
});
App.Router.map(function() {
this.route('projects_list', { path: 'projects' });
this.route('project', { path: 'projects/:project_id' });
});
App.ProjectsController = Ember.Controller.extend({
});
var PROJECTS = [
{
id: 1,
title: 'Project 1'
},
{
id: 2,
title: 'Project 2'
}
];
App.ProjectsListRoute = Ember.Route.extend({
model: function() {
return PROJECTS;
}
});
App.ProjectRoute = Ember.Route.extend({
model: function(params) {
if (!PROJECTS[params.project_id]) {
return null;
}
return PROJECTS[params.project_id];
}
});
</script>
</body>
</html>
@dreikanter
Copy link
Author

Sources:

@Dunnzilla
Copy link

As you update this, could you keep a section in here stating which version of Ember this is valid for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment