Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Introduction to Ember Model


May 09, 2021 Ember.js Reference documents


Table of contents


Ember's official website took a lot of time to model controller previous controller is simply a world of difference ah!

This chapter, which begins with Ember's model, is also the last chapter in the Ember Foundation section and is very important (believe it or not I believe it anyway).

Get ready before you start learning model Re-create an Ember project, still created using the Ember CLI command.

  1. ember new chapter6_models
  2. cd chapter6_models
  3. ember server

When you execute a project in your browser, you see the following information to indicate that the project was successfully built. Welcome to Ember

The code used in this chapter demonstration can be obtained from https://github.com/ubuntuvim/my_emberjs_code/tree/master/chapter6_models .

Before model introduce firebase into your project. P lease move the relevant configuration material here (register the user in the https://www.firebase.com/ page). F irebase's official website provides a version dedicated to Ember, as well as very simple examples. V ery detailed code tutorials are given from installation to consolidation. Here are my integration steps (commands are executed in the project directory):

  • Installation
    1. ember install emberfire

    adapter(app/adapters/application.js) is automatically created after installation, and no modifications are required to this file, and the code provided on the official website may be different from the code for your project, which should be an older version of the official website.

  • Configure config/environment.js modify the eighth line firebase: 'https://YOUR-FIREBASE-NAME.firebaseio.com/' T his address is what you get when you register your users. Y ou can view your address from here. For example, the position shown in the figure below

Introduction to Ember Model

  • Add the following code after the app .js APP:{} config/enviroment.js (approximately line 20).
    1. APP: {
    2. // Here you can pass flags/options to your application instance
    3. // when it is created
    4. },
    5. contentSecurityPolicy: {
    6. 'default-src': "'none'",
    7. 'script-src': "'self' 'unsafe-inline' 'unsafe-eval' *",
    8. 'font-src': "'self' *",
    9. 'connect-src': "'self' *",
    10. 'img-src': "'self' *",
    11. 'style-src': "'self' 'unsafe-inline' *",
    12. 'frame-src': "*"
    13. }

    Then comment out the original properties of line 7 firebase automatically generated, but the configuration is not contentSecurityPolicy

Or you can refer to my profile:

  1. /* jshint node: true */
  2. module.exports = function(environment) {
  3. var ENV = {
  4. modulePrefix: 'chapter6-models',
  5. environment: environment,
  6. // contentSecurityPolicy: { 'connect-src': "'self' https://auth.firebase.com wss://*.firebaseio.com" },
  7. firebase: '你的firebase连接',
  8. baseURL: '/',
  9. locationType: 'auto',
  10. EmberENV: {
  11. FEATURES: {
  12. // Here you can enable experimental features on an ember canary build
  13. // e.g. 'with-controller': true
  14. }
  15. },
  16. APP: {
  17. // Here you can pass flags/options to your application instance
  18. // when it is created
  19. },
  20. contentSecurityPolicy: {
  21. 'default-src': "'none'",
  22. 'script-src': "'self' 'unsafe-inline' 'unsafe-eval' *",
  23. 'font-src': "'self' *",
  24. 'connect-src': "'self' *",
  25. 'img-src': "'self' *",
  26. 'style-src': "'self' 'unsafe-inline' *",
  27. 'frame-src': "*"
  28. }
  29. };
  30. // 其他代码省略……
  31. return ENV;
  32. };

If you do not start the project with this configuration, the browser will prompt for a bunch of errors. T his is primarily a number of access issues. The project needs to be restarted after configuration to take effect!

1, introduction

model an object that is used to render the underlying data to the user. D ifferent apps have different model depending on what model is model solve the model

model are usually persistent. T his means that the user closing the browser window model should not be lost. T o ensure model data is not lost, you need to model data to the server you specify or to a local data file.
It is very common for model data model sent to the server via HTTP in JSON format and stored in the service. E mber hasn't yet developed an easier way to do this: use IndexedDB (using a database in a browser). T his is done by model data locally. O r use Ember Data, or use firebase, to save data directly to a remote server, and I'll introduce firebase to save the data to a remote server in subsequent articles.

Ember uses adapter mode to connect to the database and can adapt different types of back-end databases without modifying any network code. Y ou can see almost all Ember-supported databases on emberobserver.

If you want to integrate your Ember application with your remote server, it doesn't matter if the JSON API several times is not specification JSON data, Ember Data can configure any server to return data.

Ember Data also supports streaming media servers, such as WebSocket. Y ou can open a socket to connect to a remote server, get the latest data, or push the changed data to a remote server for saving.

Ember Data gives you an easier way to manipulate data, manage data loading uniformly, and reduce program complexity.
For model and Ember Data's introduction to this end, the official website used a lot of space to introduce Model, here I write out! I t's too long to write it and no one's going to !!! I f you're interested in watching it for yourself! ion.
Let's start with a simple example that extends to the core concept of model The code is old-fashioned, and this article will not really be executed just to illustrate the problem.

  1. // app/components/list-of-drafts.js
  2. export default Ember.Component.extend({
  3. willRender() {
  4. // ECMAScript 6语法
  5. $.getJSON('/drafts').then(data => {
  6. this.set('drafts', data);
  7. });
  8. }
  9. });

A component class is defined. a nd get the json format data in the component class. The following is the template file for the component.

  1. <ul>
  2. {{#each drafts key="id" as |draft|}}
  3. <li>{{draft.title}}</li>
  4. {{/each}}
  5. </ul>

Define another component class and template

  1. // app/components/list-button.js
  2. export default Ember.Component.extend({
  3. willRender() {
  4. // ECMAScript 6语法
  5. $.getJSON('/drafts').then(data => {
  6. this.set('drafts', data);
  7. });
  8. }
  9. });
  1. {{#link-to ‘drafts’ tagName=’button’}}
  2. Drafts ({{drafts.length}})
  3. {{/link-to}}

The list-of-drafts class is the same as the component list-button class, but their corresponding templates are different. B ut they all get the same data from remote servers. I f there is model of the core contents of the Store each time both templates are rendered, the component class calls remote data once. A nd the data returned is the same. T his invisibly adds unnecessary requests, temporarily uses unnecessary broadband, and the user experience is not good. B ut with Store you can think Store as a repository, where you get data in the Store each time you execute a class, if you don't get it remotely. When you change some data in one component, the changes to the data can also be understood to be reflected on another component that gets the data (as with automatic updates to compute properties), which no longer needs to go to the service request to get the most recently changed data.

The following will introduce you to some of the core things about Ember Data: models records adapters store

2, the core concept

Statement: Excerpted from the following http://www.emberjs.cn/guides/models/#toc.

1,store

store the central repository where your app holds records. Y ou can think of store as a cache of all the data applied. The shared store is accessible to both the app's controllers and store and when they need to display or modify a record, they first need to access the store.

DS.Store of the Store is automatically created and shared by all objects in the app.

store can be seen as a cache. The cache cache combined store description.

The following example combines the firebase demo: Create a route and model

  1. ember g route store-example
  2. ember g model article

  1. // app/models/article.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. title: DS.attr('string'),
  5. body: DS.attr('string'),
  6. timestamp: DS.attr('number'),
  7. category: DS.attr('string')
  8. });

This is model this chapter is about it! W hy aren't id properties defined? Ember the id default.

We get remote model the model callback of the route and display it on the template.

  1. // app/routes/store-example.js
  2. import Ember from 'ember';
  3. export default Ember.Route.extend({
  4. model: function() {
  5. // 从store中获取id为JzySrmbivaSSFG6WwOk的数据,这个数据是我在我的firebase中初始化好的
  6. return this.store.find('article', '-JzySrmbivaSSFG6WwOk');
  7. }
  8. });

find argument of the find method is the model class name, and the id property value of the second parameter object. Remember that id properties don't model defined manually in the model class, and Ember automatically defines them for you.

  1. <h1>{{model.title}}</h1>
  2. <div class="body">
  3. {{model.body}}
  4. </div>

Once the page is loaded, you can see the data you get.

Introduction to Ember Model

Here are some screenshots of the data on my firebase.

Introduction to Ember Model

You can see that the id -JzySrmbivaSSFG6WwOk More information about the operation of the data is described in more detail later.

2,model

The model to the concept of model has been covered and will not be repeated here. model definition:

model are made up of several properties. attr method specify the type of property.

  1. export default DS.Model.extend({
  2. title: DS.attr('string'), // 字符串类型
  3. flag: DS.attr('boolean'), // 布尔类型
  4. timestamp: DS.attr('number'), // 数字类型
  5. birth: DS.attr(‘date’) //日期类型
  6. });

The model also declares its relationship to other objects. For example, an Order can have LineItems and LineItem can belong to a specific Order

  1. App.Order = DS.Model.extend({
  2. lineItems: DS.hasMany('lineItem')
  3. });
  4. App.LineItem = DS.Model.extend({
  5. order: DS.belongsTo('order')
  6. });

The relationship between this and the table of data is the same.

3,record

record is model of a model that contains data loaded from the server side. The app itself can also create new records and save them to the server side.

Records are uniquely identified by two properties:

  1. The model type
  2. A globally unique ID

For example, the previous article is find side. The result is a record

4,adapter

An adapter is an object that understands the back end of a particular server and is primarily record and changes to the correct request calls to the server side.

For example, if your app ID record with an person 1 how does Ember Data load the object? I s it through HTTP or Websocket? If it is through HTTP, will the URL /person/1 /resources/people/1

The adapter is responsible for handling all similar issues. W henever an app needs to get store from the store that is not cached, the app accesses the adapter to get the record. If a record is changed and you are ready to save the change, store passes the record to the adapter, which is then responsible for sending the data to the server side and confirming that the save was successful.

5,cache

store caches records. I f a record is already loaded, the same object instance is returned when it is accessed again. This greatly reduces round-trip communication with the server side, allowing applications to render the desired UI for the user more quickly.

For example, the first time an store record with an ID 1 person it gets data for the object from the server side.

However, when the app ID record with person ID 1 store finds that the record has been obtained and that the record is cached. T he store no longer sends a request to the server side to get the recorded data, but instead returns the record that was acquired and constructed the first time. This feature allows the same record object, also known as Identity Map to be returned no matter how many times the record is requested.

Using identifier mapping is important because it ensures that modifications to a record on one UI are automatically propagation to other UIs used by the UI to that record. This means that you don't have to manually keep objects in ID use the ID to get the records your app has already acquired.

3, an introduction to the architecture

The first time the app store from the store that the local cache does not have a copy of the requested record, and a request is made to the adapter. The adapter gets records from the persistence layer, which is typically an HTTP service through which a JSON represents JSON

Introduction to Ember Model

As shown in the figure above, the adapter sometimes does not return the requested records immediately. At this point, the adapter must initiate an asynchronous request to the server, and when the request is loaded, records can be created from the returned data.

Because of this asynchronousity, store find() a promise from the find() promise I n addition, if all store to interact with the adapter, a commitment is returned. O nce a request to the server side returns JSON data for the requested record, the adapter fulfills its commitment and JSON to store store then gets JSON JSON the record and uses the newly loaded record to fulfill the promise that has been returned to the app.

Introduction to Ember Model

Here's what happens when store has cached the requested records.

Introduction to Ember Model

In this case, store cached the requested records, but it will also return a promise that, in the case of the cached records, will be fulfilled immediately. At this point, store already has a copy, there is no need to request from the adapter (no interaction with the server).

models records adapters store concepts you have to understand. This is the core of Ember Data.

There are more concepts about the above that will be demonstrated in code in a later article. U nderstand that the model of this article model is not a problem!!!
The full code of the blog post is placed in Github (the blog post has been modified several times, and the code on the blog post may be different from the github code, but the impact is small!). I f you think the blog post is a bit useful to you, please give me a star on the star project. Yours is definitely the biggest motivation for me!!