Philosophy of Ember.js

Recently, there has been a tendency on the web to thin the server and thicken the client. Every day there are more and more full-stack developers, and there is less and less net backend. For the past 2 years, I have been working as a Ruby on Rails developer, and in the near future I would not want to be without work. Therefore, I began to consider options for studying the client framework.

There were several options:

  • Meteor
  • Angular
  • Ember

But only one should remain. Meteor offers an interesting concept - common client and server code, but it is still damp and I did not want to leave the beautiful Ruby language. Therefore, the Meteor fell away. Since Ember was similar to Rails (magic, convention over configuration), it was he who was chosen. In addition, the Handlebars template engine looked very nice compared to Angular directives.

The choice is made. This is where the problems started.

The manual is written very well, everything is done well, but when you start to do something yourself, constant questions arise. The main problem I had was that I did not see the whole picture, did not understand architecture. There are few articles on this subject, and those that exist talk about the most basic concepts, which is why this article appeared.

Ember is called the MVC framework, so I expected to see something similar to Ruby on Rails and classic MVC. But it was not there! In addition to the model, view, and controller (which do very different things than on the server), there were many different things: components, routes, adapters, serializers, templates, storage.

The entry threshold is high and it was quite difficult to put all this together in one’s head, to understand what interacts with what. That is why I want to share with you a small Ember diagram, it describes the operation of components, their interaction. I hope it helps you with understanding what is happening in the application, learning it and faster and easier entry than I had.

Request Life Path


image

Consider the scheme in more detail.

Point of entry


We have a one-page application, so we have one entry point - index.html . All transitions will be done using the anchor or history api. All paths will be working, that is, you can easily bookmark the desired page and the content will be available on it.

Router


First of all, Router works for us. It is he who chooses what to do next depending on the address and transfers control to the route indicated in it.

Route


Route processes incoming data, such as url parameters, and accesses models or models. It is the link between the data (Model) and its processor (Controller).

Model


Models are our entities, for example, in a blog post, user, comment. Not pure Ember is already used here, but its addition - Data.
In order to get these objects, there are 2 options:

  1. Get them using the API.
  2. Get from the local storage where the data was added at the last request in the API.


When working with the storage, everything is simple - the data there already lies in the form of objects and when requested, get from there, but for working with the API, 2 more entities are used: adapters and serializers.

  1. Adapters set the rules for working with the API, for example, get all posts - GET / posts, and update the post - PUT / posts / 1.
  2. Serializers parse the server json response and set the json request format.


Controller


When we received the data, we can begin to process it. It is in the controller that computed properties are described. Controllers come in several forms:
  1. Controller - a regular controller, for example for static pages.
  2. ObjectController - to represent a single object.
  3. ArrayController - to represent an array of objects, it may also have a nested ObjectController for each object (for example, for the computed properties of each object) [1]

Representation


After that it is necessary to draw our data. Here, templates, views and components come to our aid. First, let's talk about templates - sections of html code into which our data is inserted. They may contain partials, components, and views.

Now let's talk about views and components. Components are inheritors of representations, therefore both that, and the second are repeated sections of the code. In connection with the imminent transition to version 2.0 [2], we are advised to use only components.

Components - integral pieces of code responsible for one function and which will be used in different places. Let's take an example from life: I needed the long text to automatically collapse and the “Expand” button to appear. That's what I used components for.

Partials are the same templates that are inserted into other templates; all this applies to them in exactly the same way.

Actions / Events


Now you need to talk a little about actions and action bubbling - a chain of actions.
Actions - what happens during certain events (clicking on an element, submitting a form). They are described in controllers, routes, views, components.
Consider a small piece of code:

// index.hbs

{{post.title}}


// index-controller.js
App.IndexController = Ember.Controller.extend({
  actions: {
    doSomething: function() {
      console.log('Вы только что нажали на заголовок')
    }
  }
})

When you click on the title, this event will be transferred to the appropriate controller and processed there - in this case it will display the inscription in the browser console.

Action bubbling

Action bubbling is an event transmission up the chain if a handler was not found in the route / controller.
Let us have such routes, controllers and views:

// post-route.js
App.PostsRoute = Ember.Route.extend({
  actions: {
    doSomething: function() {
      // 1
    }
  }
})
// posts-controller.js
App.PostsController = Ember.ArrayController.extend({
  itemController: 'post'
  actions: {
    doSomething: function() {
      // 2
    }
  }
}) 
// post-controller.js
App.PostController = Ember.ObjectController.extend({
  actions: {
    doSomething: function() {
      // 1
    }
  }
})


// posts.hbs
{{#each post in controller}}
  

{{post.title}}

{{/each}}


When you click on the title of the post, the most immediate action will be performed - i.e. in PostController, if it is not there, it will move to a higher level, and so on.

Here is the same in diagram form:

image


In general terms, the life cycle of a single request in the Ember application looks like this, and I hope it helps you with an understanding of the architecture and the start of exploring this wonderful framework.

PS: If it will be interesting, in the next article I will talk about writing an application in EmberJS, integration with Ruby on Rails, additional packages and Ember CLI.

Also popular now: