But for some reason they were afraid to ask.
Models - quite an important part of the application, because without data nowhere.
In this article I will try to highlight in detail all aspects of using models in the MVC framework for developing mobile applications Appcelerator Titanium.
')
If you have not tried to contact the models, then I hope this article will save you a couple of kilometers of nerves.
Backbone.js
So the first thing to know when working with models in Titanium is that they are based on models and collections from Backbone. This means, firstly, you can use all the properties and methods described in the Backbone documentation; secondly, it will not be very superfluous to get acquainted with her, if you have not already done so.
Just in case, I will focus on terminology: a model is a single entity, a collection is a collection of similar models.
Important: Titanium uses Backbone version 0.9.2, so some methods from the Backbone documentation may not be implemented.
Underscore.js
Collections also inherit Underscore.js methods to make a developer’s life easier. For example, the
.map method
Creature
You can create a model in two equivalent ways: using Appcelerator Studio or manually.
You can manually create a custom file in the <project> / app / models / folder (which the studio actually does for you):
Model Description File Formatexports.definition = { config : {
If you are using a studio, simply call the context menu of the project and select the item “New -> Alloy Model”. When creating a dialog box prompts you to choose an adapter type: localStorage, properties or sql. Adapter types are described below.
All you need to describe in this file for basic functionality is the config block. It contains the data schema and type of sync adapter. This block should contain the following fields:
- columns : dictionary describing model fields. The key is the name of the field, the value is the type. Types as in SQLite: string, varchar, int, tinyint, smallint, bigint, double, float, decimal, number, date, datetime, and boolean
- defaults : the same dictionary as the columns, but now the values ​​are the default field values ​​if one of them is not defined during synchronization
- adapter : this object contains two fields:
- type : type of sync adapter
- collection_name : collection name. May differ from model name. You will use the value of this field to create a collection.
- idAttribute : primary key
For example, we create a model of books. To do this, create the books.js file in the <project> / app / models / folder:
An example of a created model exports.definition = { config: { "columns": { "title": "String", "author": "String"
Here we have a model with two text fields: the name of the book and the author. Both fields default to "-". So far, everything is simple.
The adapter type sql says that when trying to get data, the model will use the built-in adapter to try to connect to the SQLite database on the device and retrieve data from the books table.
Own properties and methods in the model can be added as follows:
Model Extension Example exports.definition = { config : {
The same goes for collections. If you add your own methods to extendModel, they will be available in the model, but the collection does not, and vice versa.
Using
There are two ways to access the model / collection:
- Creating a global singleton
- Creating a local link
- By specifying XML markup if you are using Alloy
Global singleton
In this case, the model will be available immediately everywhere, in all controllers. If it is already declared in one, then in another the method call
Alloy.Models.instance will return a reference to this declared model. An example is the User model, it can be the same everywhere.
Similarly for collections.
Local link
You can create a local reference using the
Alloy.createModel method. Then this model will be available only inside the controller where it was created. The method is a factory, transfer to it the model name (file name minus .js) and parameters. And that's all.
Similarly for collections.
XML
The <Model> markup element must be a
direct descendant of <Alloy>. And it must have an src attribute with the value “model-filename-model-minus-.js”. Then a singleton of this model will be available in the controller in the Alloy.Models namespace:
XML <Alloy> <Model src="book" /> <Window> <TableView id="table" /> </Window> </Alloy>
Controller var drama = Alloy.Models.book; drama.set('title', ' '); drama.set('author', ' ');
This element also has an instance attribute. If it is true, a link to the model will be created (local, available only within one controller). By the way, in this case, the model will not have access in the Alloy.Models namespace, it will need to be addressed by id:
XML <Alloy> <Model id="myBook" src="book" instance="true"/> <Window> <TableView id="table" /> </Window> </Alloy>
Controller var drama = $.myBook; drama.set('title', ' '); drama.set('author', ' ');
Similarly for collections.
Sync adapters
Finally we got to the section, which was promised in the "Creation" section. To work with models it is not enough just to describe the data scheme. We still need to connect them to something. This connection is the sync adapter.
The adapter is an implementation of Backbone.sync. Since the most common task is CRUD operations on a remote server (well, personally from my experience), by default the Backbone.sync method makes RESTful JSON requests for the addresses that you specify in the Model.urlRoot and Collection.url properties. So says the official documentation. In practice, in order to make sense of the models / collections, it is very convenient to use the adapter restapi, which I will talk about later. For now, let's return to the official documentation.
Adapters can be of four types:
- sql
- properties
- localStorage (since version 1.5.0 is not used, so we will not consider it)
- your type
SQL
If the idAttribute key is not defined in the config section of the adapter, then Alloy itself will generate the alloy_id field in your table and will use it as the primary key.
Pay attention to the db_file and db_name config fields (in the "Creation" section). Here they are important.
Unlike other types, in this method
Backbone.Collection.fetch can accept a whole SQL query string:
Query string in .fetch () var library = Alloy.createCollection('book');
That is, if you want a simple query, pass an object with the query key in the parameters, and if you want a complex query, pass both the query and the parameters.
By the way, you can still pass the key id. In this case, the adapter itself will understand that you want to use the WHERE id =? Restriction.
id myModel.fetch({id: 123});
properties
If your database is not SQLite, then you can create your adapter and do whatever you want with the data. To do this, create an adapter file in the app / assets / alloy / sync or app / lib / alloy / sync directory, for example, myAdapter.js, and then specify the name of this file, that is, "myAdapter", in the model's config.type.
Actually this file should export three functions:
- module.exports.beforeModelCreate (config) (optional) - the method, as the name implies, is performed before creating the model. The parameters passed to the config of this model. Here, for example, you can add baseUrl to the request address. Returns a modified config object
- module.exports.afterModelCreate (optional) - takes two parameters: the newly created Backbone.Model class and the name of the model file
- module.exports.sync - implementation of the Backbone.sync method. It must return data
If you need to receive data from a remote server, and you don’t want to create your own adapter, there is a wonderful restapi adapter, which is not included in the number of built-in ones, but does its job (RESTful JSON requests) with a bang.
The minimum required settings are the URL field in the config file:
Sample model with restapi adapter exports.definition = { config: { "URL": "http://example.com/api/modelname",
Of course, this is not all available settings, for a full list, see the documentation. What is more important in this adapter is that the fetch method in it accepts a dictionary with three possible fields:
- data request parameters
- success callback for successful request
- error callback for error
Conclusion
So, this is all you need to know in order to be able to work with models in Titanium at a basic level. This topic is somewhat broader, for example, I deliberately omitted here a description of the migration process between different versions of the database, data binding, using models without Alloy, and working with SQLite. I hope to fill all these gaps in the next article, stay tuned.
This article is based on a) official documentation; b) own experience of using models in Alloy. If among the community there are people who understand this issue better than me and see errors or inaccuracies, please comment, discuss.