Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A lightweight model library for Ember.js

License

NotificationsYou must be signed in to change notification settings

ebryn/ember-model

Repository files navigation

Introduction

Ember Model (EM) is a simple and lightweight model library for Ember. It intentionally supports a limited feature set. The main goal is to provide primitives on top of $.ajax that are required by Ember.

EM is still a work in progress, but it's flexible and stable enough to beused in production apps today. It was extracted out of an Ember app. Please see the issues section for a list of bugs and planned features.

Getting Started with Ember Model

Ember CLI

ember install ember-model

Bower

bower install ember-model --save

Getting started Embercast

Need more help getting started? Join us in #ember-model on Freenode.

Features

  • BYO$A (bring your own $.ajax)
  • Relationships (hasMany/belongsTo)
  • Focused on performance
  • Automatic coalescing of multiple findById calls into a single findMany
  • Fixtures
  • Identity map (per class)
  • Promises everywhere
  • Customizable RESTAdapter

If you want more features than Ember Model provides, file an issue. Feature requests/contributions are welcome but the goal is to keep things simple and fast.

Example usage

Ember CLI / ES6 modules

// app/models/user.jsimport{Model,attr,hasMany}from'ember-model';varUser=Model.extend({id:attr(),name:attr(),comments:hasMany("comment",{key:'comment_ids'})}).reopenClass({url:"/users"});exportdefaultUser;
// app/models/comment.jsimport{Model,attr,hasMany}from'ember-model';varComment=Model.extend({id:attr(),text:attr()}).reopenClass({url:"/comments"});exportdefaultComment;
// create examplevarnewUser=this.store.createRecord('user',{name:"Erik"});newUser.save();// POST to /users// hasMany examplevarcomments=newUser.get('comments');comments.create({text:"hello!"});comments.save();// POST to /comments// find & update examplethis.store.find('user',1).then(user=>{// GET /users/1user.set('name','Kris');user.get('isDirty');// => trueuser.save();// PUT /users/1});

Globals

varattr=Ember.attr,hasMany=Ember.hasMany;// Model definitionsApp.User=Ember.Model.extend({id:attr(),name:attr(),comments:hasMany("App.Comment",{key:'comment_ids'})});App.User.url="/users";App.User.adapter=Ember.RESTAdapter.create();App.Comment=Ember.Model.extend({id:attr(),text:attr()});App.Comment.url="/comments";App.Comment.adapter=Ember.RESTAdapter.create();// create examplevarnewUser=App.User.create({name:"Erik"});newUser.save();// POST to /users// hasMany examplevarcomments=newUser.get('comments');comments.create({text:"hello!"});comments.save();// POST to /comments// find & update examplevarexistingUser=App.User.find(1);// GET /users/1existingUser.set('name','Kris');existingUser.get('isDirty');// => trueexistingUser.save();// PUT /users/1

Store API

Store#find(<type>) - find all records by type, returns a promise

Store#find(<type>, <id>) - find by primary key (multiple calls within a single run loop can coalesce to a findMany), returns a promise

Store#find(<type>, <object>) - find query - object gets passed directly to your adapter, returns a promise

Store#createRecord(<type>, <object>) - create a new record

Model API

Model.create - create a new record

Model#save - save or update record

Model#deleteRecord - delete a record

Model#load(<id>, <object>) - load JSON into the record (typically used inside adapter definition)

Model#toJSON - serialize the record to JSON

Model.find() - find all records

Model.find(<String|Number>) - find by primary key (multiple calls within a single run loop can coalesce to a findMany)

Model.find(<object>) - find query - object gets passed directly to your adapter

Model.fetch() - find all records, returns a promise

Model.fetch(<String|Number>) - find by primary key (multiple calls within a single run loop can coalesce to a findMany), returns a promise

Model.fetch(<object>) - find query - object gets passed directly to your adapter, returns a promise

Model.load(<array>) - load an array of model data (typically used when preloading / sideloading data)

Adapter API

Ember.Adapter=Ember.Object.extend({find:function(record,id){},// find a single recordfindAll:function(klass,records){},// find all recordsfindMany:function(klass,records,ids){},// find many records by primary key (batch find)findQuery:function(klass,records,params){},// find records using a querycreateRecord:function(record){},// create a new record on the serversaveRecord:function(record){},// save an existing record on the serverdeleteRecord:function(record){}// delete a record on the server});

Attribute types

Attributes by default have no type and are not typecast from the representationprovided in the JSON format.

Built in attribute types

Ember Model has built inDate andNumber types. TheDate type will deserializestrings into a javascript Date object, and will serialize dates intoISO 8601 format. TheNumber type willcast into a numeric type on serialization and deserialization.

App.Post=Ember.Model.extend({date:attr(Date),comment_count:attr(Number)});

Custom attribute types

To provide custom attribute serialization and deserialization, create an object thathas serialize and deserialize functions, and pass it into the attr helper:

varTime={serialize:function(time){returntime.hour+":"+time.min;},deserialize:function(string){vararray=string.split(":");return{hour:parseInt(array[0],10),min:parseInt(array[1],10)};}};varPost=Ember.Model.extend({time:attr(Time)});

Default values

Attributes can have a default value.

App.Post=Ember.Model.extend({tags:attr(Array,{defaultValue:[]})});

Relationships

Ember Model provides two types of relationshipshasMany andbelongsTo. Both types of relationships can either be embedded or referenced by ids.

Defining Relationships

Relationships are defined by using relationship computed property macros in place ofEmber.attr. There are two macros available, one for each type of relationship.

Ember.belongsTo(type, options) - Provides access to a single related object.

Ember.hasMany(type, options) - Provides access to an array of related objects.

Both relationships take two arguments.

  • type - Class of the related model or string representation (eg. App.Comment or 'App.Comment').

  • options - An object with two properties,key which is required andembedded which is optional and defaults tofalse.

    • key - indicates what property of the JSON backing the model will be accessed to access the relationship
    • embedded - Iftrue the related objects are expected to be present in the data backing the model. Iffalse only the primaryKeys are present in the data backing the model. These keys will be used to load the correct model.

Relationship Examples

// Embedded Relationship ExamplepostJson={id:99,title:'Post Title',body:'Post Body',comments:[{id:1,body:'comment body one',},{id:2,body:'comment body two'}]};App.Post=Ember.Model.extend({id:Ember.attr(),title:Ember.attr(),body:Ember.attr(),comments:Ember.hasMany('App.Comment',{key:'comments',embedded:true})});App.Comment=Ember.Model.extend({id:Ember.attr(),body:Ember.attr()});
// ID-based Relationship ExamplepostJson={id:99,title:'Post Title',body:'Post Body',comment_ids:[1,2]};commentsJson=[{id:1,body:'Comment body one',post_id:99},{id:2,body:'Comment body two',post_id:99}];App.Post=Ember.Model.extend({id:Ember.attr(),title:Ember.attr(),body:Ember.attr(),comments:Ember.hasMany('App.Comment',{key:'comment_ids'})});App.Comment=Ember.Model.extend({id:Ember.attr(),body:Ember.attr(),post:Ember.belongsTo('App.Post',{key:'post_id'})})

Working with relationships

Working with abelongsTo relationship is just like working any otherEmber.Model. AnEmber.Model instance is returned when accessing abelongsTo relationship, so anyModel methods can be used such assave() orreload().

comment.get('post').reload();// Reloads the comments postpost.get('comments.lastObject').save();// Saves the last comment associated to post

Accessing ahasMany relationship returns aHasManyArray or anEmbeddedHasManyArray which have useful methods for working with the collection of records. On any type ofhasMany relationship you can callsave() and all the dirty records in the collection will have theirsave() methods called. When working with an embeddedhasMany relationship you can use thecreate(attrs) method to add a new record to the collection.

post.get('comments').save();// Saves all dirty comments on post// Below only works on embedded relationshipspost.get('comments').create({body:'New Comment Body'});// Creates a new comment associated to post

Customizing

There are a few properties you can set on your class to customize how eitherEmber.Model orEmber.RESTAdapter work:

primaryKey

The property Ember Model uses for a per-record unique value (default: "id").

App.User=Ember.Model.extend({token:attr(),name:attr()});App.User.primaryKey='token';
GET /users/a4bc81f90{"token": "a4bc81f90", "name": "Brian"}

rootKey

WhenRESTAdapter creates a record from data loaded from the server it willuse the data from this property instead of the whole response body.

App.User=Ember.Model.extend({name:attr()});App.User.rootKey='user';
GET /users/1{"user": {"id": 1, "name": "Brian"}}

collectionKey

WhenRESTAdapter creates multiple records from data loaded from the server itwill use the data from this property instead of the whole response body.

App.User=Ember.Model.extend({name:attr()});App.User.collectionKey='users';
GET /users{"users": [{"id": 1, "name": "Brian"}]}

camelizeKeys

If the server sends keys with underscores (ex:created_at),rather than camelized (ex:createdAt), setting this option totruemakes Ember Model automatically camelize the keys.

App.User=Ember.Model.extend({firstName:attr()});App.User.camelizeKeys=true;
GET /users/1{"id": 1, "first_name": "Brian"}
user.get('firstName')// => Brian

urlSuffix

By default no suffix is added to the url. You may want to specifically add one if using the same url for html and json requests.

App.User=Ember.Model.extend({first_name:attr()});App.User.urlSuffix='.json';
GET /users/1.json{"id": 1, "first_name": "Brian"}

Customize Ajax Settings

When usingRESTAdapter custom headers and ajax settings can be applied by extendingRESTAdapter and definingajaxSettings

App.CustomAdapter = Ember.RESTAdapter.extend({  ajaxSettings: function(url, method) {    return {      url: url,      type: method,      headers: {        "authentication": "xxx-yyy"      },      dataType: "json"    };  }});

or it can be done at create time of the RESTAdapter

App.User.adapter = Ember.RESTAdapter.create({  ajaxSettings: function(url, method) {    return {      url: url,      type: method,      headers: {        "authentication": "xxx-yyy"      },      dataType: "json"    };  }});

Building Ember Model

Ember Model usesnode.js andgrunt as a build system,These two libraries will need to be installed before building.

To build Ember Model, clone the repository, and runnpm install to install build dependenciesandgrunt to build the library.

Unminified and minified builds of Ember Model will be placed in thedistdirectory.

How to Run Unit Tests

Setup

Ember Model usesnode.js andgrunt as a build systemand test runner, andbower for dependency management.

If you have not used any of these tools before, you will need to runnpm install -g bower andnpm install -g grunt-cli to be able to use them.

To test Ember Model runnpm install to install build dependencies,bower install to install theruntime dependencies andgrunt test to execute the test suite headlessly via phantomjs.

If you prefer to run tests in a browser, you may start a development server usinggrunt develop. Tests are available athttp://localhost:8000/tests

Who's using Ember Model?

Are you using Ember Model? Submit a pull request to add your project to this list!

Special Thanks

Yehuda Katz (@wycats), Tom Dale (@tomdale), Igor Terzic (@igorT), and company for their amazing work on Ember Data. I believe it's the most ambitious JS project today. The goal is someday everyone's JSON APIs will be conventional enough that Ember Data will be the best choice of data library for Ember. Until then, Ember Model will make it easy to get up and running quickly with Ember.

Bitdeli Badge


[8]ページ先頭

©2009-2025 Movatter.jp