@maccesar/titools 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +1 -1
- package/README.md +31 -60
- package/agents/ti-pro.md +3 -1
- package/commands/ti-audit.md +6 -4
- package/docs/examples.md +9 -0
- package/docs/knowledge-index.md +2 -1
- package/lib/config.js +1 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +18 -179
- package/skills/alloy-guides/references/CLI_TASKS.md +17 -216
- package/skills/alloy-guides/references/CONCEPTS.md +27 -162
- package/skills/alloy-guides/references/CONTROLLERS.md +38 -236
- package/skills/alloy-guides/references/MODELS.md +47 -723
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +21 -482
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +12 -222
- package/skills/alloy-guides/references/VIEWS_STYLES.md +39 -358
- package/skills/alloy-guides/references/VIEWS_XML.md +36 -552
- package/skills/alloy-guides/references/WIDGETS.md +49 -127
- package/skills/alloy-howtos/SKILL.md +14 -169
- package/skills/alloy-howtos/references/best_practices.md +9 -113
- package/skills/alloy-howtos/references/cli_reference.md +18 -223
- package/skills/alloy-howtos/references/config_files.md +50 -133
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +19 -63
- package/skills/alloy-howtos/references/samples.md +21 -138
- package/skills/ti-api/SKILL.md +10 -2
- package/skills/ti-api/references/api-android.md +36 -2
- package/skills/ti-api/references/api-app-platform.md +39 -3
- package/skills/ti-api/references/api-core.md +50 -18
- package/skills/ti-api/references/api-data-network.md +49 -35
- package/skills/ti-api/references/api-media.md +45 -27
- package/skills/ti-api/references/api-services.md +39 -9
- package/skills/ti-api/references/api-ui-android.md +33 -13
- package/skills/ti-api/references/api-ui-extras.md +41 -15
- package/skills/ti-api/references/api-ui-ios-animator.md +42 -26
- package/skills/ti-api/references/api-ui-ios.md +74 -2
- package/skills/ti-api/references/api-ui-lists.md +32 -16
- package/skills/ti-api/references/api-ui-text-input.md +34 -17
- package/skills/ti-api/references/api-ui-views.md +27 -1
- package/skills/ti-api/references/api-ui-windows-navigation.md +32 -18
- package/skills/ti-api/references/api-xml-global.md +66 -16
- package/skills/ti-create-release/SKILL.md +98 -0
- package/skills/ti-create-release/references/module-discovery.md +69 -0
- package/skills/ti-expert/references/adaptive-layouts.md +1 -1
- package/skills/ti-guides/SKILL.md +37 -76
- package/skills/ti-guides/references/advanced-data-and-images.md +122 -126
- package/skills/ti-guides/references/android-manifest.md +24 -83
- package/skills/ti-guides/references/app-distribution.md +31 -377
- package/skills/ti-guides/references/application-frameworks.md +127 -335
- package/skills/ti-guides/references/cli-reference.md +184 -633
- package/skills/ti-guides/references/commonjs-advanced.md +81 -231
- package/skills/ti-guides/references/compatibility-matrix.md +36 -75
- package/skills/ti-guides/references/hello-world.md +95 -70
- package/skills/ti-guides/references/hyperloop-native-access.md +52 -448
- package/skills/ti-guides/references/resources.md +174 -142
- package/skills/ti-guides/references/sdk-release-notes.md +28 -71
- package/skills/ti-guides/references/tiapp-config.md +222 -598
- package/skills/ti-howtos/SKILL.md +23 -123
- package/skills/ti-howtos/references/cross-platform-development.md +119 -324
- package/skills/ti-howtos/references/debugging-profiling.md +77 -445
- package/skills/ti-howtos/references/extending-titanium.md +199 -673
- package/skills/ti-howtos/references/local-data-sources.md +87 -300
- package/skills/ti-howtos/references/location-and-maps.md +86 -213
- package/skills/ti-howtos/references/media-apis.md +103 -223
- package/skills/ti-howtos/references/notification-services.md +86 -506
- package/skills/ti-howtos/references/remote-data-sources.md +97 -316
- package/skills/ti-howtos/references/using-modules.md +77 -133
- package/skills/ti-ui/SKILL.md +28 -143
- package/skills/ti-ui/references/icons-and-splash-screens.md +74 -403
- package/skills/ti-ui/references/layouts-and-positioning.md +175 -402
- package/skills/ti-ui/references/listviews-and-performance.md +100 -703
- package/skills/ti-ui/references/platform-conventions.md +180 -0
- package/skills/ti-ui/references/user-interface.md +43 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
- package/skills/alloy-howtos/references/custom_tags.md +0 -148
- package/skills/ti-guides/references/coding-best-practices.md +0 -149
- package/skills/ti-guides/references/javascript-primer.md +0 -414
- package/skills/ti-guides/references/reserved-words.md +0 -36
- package/skills/ti-guides/references/style-and-conventions.md +0 -103
- package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -624
- package/skills/ti-howtos/references/automation-fastlane-appium.md +0 -96
- package/skills/ti-howtos/references/buffer-codec-streams.md +0 -162
- package/skills/ti-howtos/references/google-maps-v2.md +0 -172
- package/skills/ti-howtos/references/ios-map-kit.md +0 -149
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +0 -611
- package/skills/ti-howtos/references/tutorials.md +0 -565
- package/skills/ti-howtos/references/web-content-integration.md +0 -287
- package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -124
- package/skills/ti-ui/references/accessibility-deep-dive.md +0 -288
- package/skills/ti-ui/references/animation-and-matrices.md +0 -569
- package/skills/ti-ui/references/application-structures.md +0 -626
- package/skills/ti-ui/references/custom-fonts-styling.md +0 -549
- package/skills/ti-ui/references/event-handling.md +0 -401
- package/skills/ti-ui/references/gestures.md +0 -448
- package/skills/ti-ui/references/orientation.md +0 -374
- package/skills/ti-ui/references/platform-ui-android.md +0 -727
- package/skills/ti-ui/references/platform-ui-ios.md +0 -576
- package/skills/ti-ui/references/scrolling-views.md +0 -288
- package/skills/ti-ui/references/tableviews.md +0 -542
|
@@ -1,501 +1,40 @@
|
|
|
1
|
-
# Alloy
|
|
1
|
+
# Alloy persistence and schema migrations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use a sync adapter in the model's `config.adapter`. See [model definition and binding](./MODELS.md) for a complete model/controller/view setup.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
| Adapter | Storage | Current use |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `sql` | SQLite table | Queryable or growing data |
|
|
8
|
+
| `properties` | `Ti.App.Properties` | Small datasets |
|
|
9
|
+
| `localStorage` | HTML5 storage | Requires a web-storage environment; not a native Android/iOS adapter |
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
## Contents
|
|
11
|
+
The current guide lists all three. In released Alloy, `localStorage` directly depends on an HTML5 `localStorage` object; do not select it as native persistence simply because it is listed. `properties` serializes the complete collection on writes and slows down as it grows. Choose `sql` unless the small-dataset case fits.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
- [Sync Adapters](#sync-adapters)
|
|
14
|
-
- [Custom Sync Adapters](#custom-sync-adapters)
|
|
15
|
-
- [Migrations](#migrations)
|
|
16
|
-
- [Backbone Objects without Alloy](#backbone-objects-without-alloy)
|
|
17
|
-
- [Using Backbone Objects with Alloy Data Binding](#using-backbone-objects-with-alloy-data-binding)
|
|
18
|
-
- [Alloy Backbone Migration](#alloy-backbone-migration)
|
|
19
|
-
- [Overview](#overview)
|
|
20
|
-
- [Setup](#setup)
|
|
21
|
-
- [Summary of Changes](#summary-of-changes)
|
|
22
|
-
- [Parse Method](#parse-method)
|
|
23
|
-
- [Silent Option](#silent-option)
|
|
24
|
-
- [API Changes](#api-changes)
|
|
13
|
+
## Migrations
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## Alloy Sync Adapters and Migrations
|
|
29
|
-
|
|
30
|
-
### Sync Adapters
|
|
31
|
-
|
|
32
|
-
In Alloy, a sync adapter allows you to store and load your models to a persistent storage device, such as an on-device database or remote server. Alloy relies on the Backbone API to sync model data to persistent storage.
|
|
33
|
-
|
|
34
|
-
#### Backbone Sync
|
|
35
|
-
|
|
36
|
-
Backbone syncs your models to persistent storage devices based on the implementation of the [Backbone.sync method](https://titaniumsdk.com/docs/alloy/models). Since Backbone's primary use is for web applications, by default, the Backbone.sync method executes RESTful JSON requests to a URL specified by the Model.urlRoot or Collection.url attribute, when these classes are created.
|
|
37
|
-
|
|
38
|
-
Models are accessed from persistent storage based on the `id` attribute. To override this, set the `idAttribute` property of the model. The `cid` (client ID) is a special property of models that is automatically assigned when they are first created. Client IDs are useful when the model has not yet been saved to the server and does not have its real `id` yet.
|
|
39
|
-
|
|
40
|
-
The sync method depends on calls to other Backbone methods as described in the table below.
|
|
41
|
-
|
|
42
|
-
| **Backbone Method** | **Sync CRUD Method** | **Equivalent HTTP Method** | **Equivalent SQL Method** |
|
|
43
|
-
| ---------------------------------------------------------------- | -------------------- | -------------------------- | ------------------------- |
|
|
44
|
-
| Collection.fetch | read | GET | SELECT |
|
|
45
|
-
| Collection.create (id == null) or Collection.create (id != null) | create or update | POST or PUT | INSERT or UPDATE |
|
|
46
|
-
| Model.fetch | read | GET | SELECT |
|
|
47
|
-
| Model.save (id == null) or Model.save (id != null) | create or update | POST or PUT | INSERT or UPDATE |
|
|
48
|
-
| Model.destroy | delete | DELETE | DELETE |
|
|
49
|
-
|
|
50
|
-
#### Ready-Made Sync Adapters
|
|
51
|
-
|
|
52
|
-
Alloy provides a few ready-made sync adapters. In the 'adapter' object, set the 'type' to use one of the following:
|
|
53
|
-
|
|
54
|
-
* `sql` for the SQLite database on the Android and iOS platform.
|
|
55
|
-
* `properties` for storing data locally in the Titanium SDK context. You do not need to define the `columns` object in the `config` object. If defined, the object is ignored.
|
|
56
|
-
* `localStorage` for HTML5 localStorage on the Mobile Web platform. Deprecated since Alloy 1.5.0. Use the `properties` adapter instead.
|
|
57
|
-
|
|
58
|
-
These adapters are part of Alloy and are copied to the `Resources/alloy/sync` folder during compilation. These sync adapters assign the `id` attribute of the models, which means if you assign an ID when creating a model, it is overridden by any sync operations.
|
|
59
|
-
|
|
60
|
-
##### SQLite Sync Adapter Features
|
|
61
|
-
|
|
62
|
-
The `sql` sync adapter has a few extra features:
|
|
63
|
-
|
|
64
|
-
**Fetch method accepts SQL Query**
|
|
65
|
-
|
|
66
|
-
The Backbone.Collection.fetch method supports SQL queries as a parameter. Use `query` as the key in the dictionary object to create a simple query or query with a prepared statement.
|
|
15
|
+
Changing `columns` does not alter an existing database table. Without a migration, a later version can fail with missing-column errors. SQL migrations run in filename timestamp order:
|
|
67
16
|
|
|
68
17
|
```javascript
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// use a simple query
|
|
72
|
-
library.fetch({query:'SELECT * from ' + table + ' where author="' + searchAuthor + '"'});
|
|
73
|
-
// or a prepared statement
|
|
74
|
-
library.fetch({query: { statement: 'SELECT * from ' + table + ' where author = ?', params: [searchAuthor] }});
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Fetch method accepts ID attribute**
|
|
78
|
-
|
|
79
|
-
Since Alloy 1.3.0, to fetch a single model using its ID, pass a dictionary with one key-value pair, where `id` is the key and the model's ID as the value to retrieve that model, to the `fetch` method instead of using a SQL query. For example:
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
myModel.fetch({id: 123});
|
|
83
|
-
// is equivalent to
|
|
84
|
-
myModel.fetch({query: 'select * from ... where id = ' + 123 });
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Columns accept SQLite keywords**
|
|
88
|
-
|
|
89
|
-
The columns values accept SQLite keywords, such as AUTOINCREMENT and PRIMARY KEY. For example:
|
|
90
|
-
|
|
91
|
-
**app/models/book.js**
|
|
92
|
-
|
|
93
|
-
```javascript
|
|
94
|
-
exports.definition = {
|
|
95
|
-
config: {
|
|
96
|
-
"columns": {
|
|
97
|
-
"title": "TEXT",
|
|
98
|
-
"author": "TEXT",
|
|
99
|
-
"book_id": "INTEGER PRIMARY KEY AUTOINCREMENT"
|
|
100
|
-
},
|
|
101
|
-
"adapter": {
|
|
102
|
-
"type": "sql",
|
|
103
|
-
"collection_name": "books",
|
|
104
|
-
"idAttribute": "book_id"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Specify columns property as primary ID**
|
|
111
|
-
|
|
112
|
-
Define the `idAttribute` key-value pair in the `config.adapter` object to use a `config.columns` key as the primary ID for the SQLite table. If this key is not set, Alloy creates the `alloy_id` column in the table and generates a default GUID as the model ID.
|
|
113
|
-
|
|
114
|
-
**Specify a migration to use**
|
|
115
|
-
|
|
116
|
-
Define the `migration` key-value pair in the `config.adapter` object to specify the database version to use. The value of this key is the datetime code of the migration file. Alloy upgrades or rolls back the database based on this value. If left undefined, Alloy upgrades the database based on the newest migration file.
|
|
117
|
-
|
|
118
|
-
**Specify a database to use**
|
|
119
|
-
|
|
120
|
-
Define the `db_name` key-value pair in the `config.adapter` object to specify the name of the database to use. If left undefined, Alloy uses the default database `_alloy_`.
|
|
121
|
-
|
|
122
|
-
**Specify a database file to preload**
|
|
123
|
-
|
|
124
|
-
Define the `db_file` key-value pair in the `config.adapter` object to specify the database file ('myfile.sqlite') to preload. Place this file in the `app/assets` directory of your Alloy project. Alloy creates a database using the name of the database file minus the file extension if one does not exist.
|
|
125
|
-
|
|
126
|
-
### Custom Sync Adapters
|
|
127
|
-
|
|
128
|
-
To create a custom sync adapter, create a JavaScript file in either `app/assets/alloy/sync` or `app/lib/alloy/sync`. During compilation, this file is copied to the `Resources/alloy/sync` folder. In the `config` object of the model file, set the `type` in the `adapter` object to the name of the JavaScript file minus the '.js' extension.
|
|
129
|
-
|
|
130
|
-
The sync adapter exports three functions:
|
|
131
|
-
|
|
132
|
-
* `module.exports.beforeModelCreate` (optional) - executes code before creating the Backbone.Model class. First passed parameter is the `config` object from the model file. Second passed parameter is the name of the Alloy Model file. Returns a `config` object.
|
|
133
|
-
|
|
134
|
-
* `module.exports.afterModelCreate` (optional) - execute code after creating the Backbone.Model class. First passed parameter is the newly created Backbone.Model class. Second passed parameter is the name of the Alloy Model file.
|
|
135
|
-
|
|
136
|
-
* `module.exports.sync` - implement the Backbone.sync method.
|
|
137
|
-
|
|
138
|
-
### Migrations
|
|
139
|
-
|
|
140
|
-
A migration is a description of incremental changes to a database, which takes your database from version 1 to version X, with a migration file for each step in the evolution of your database schema. This is helpful to keep different versions of a database in sync. For example, when version 7 of your application is deployed, migrations can successfully update the database from versions 1 through 6. Currently, migrations are only used with the `sql` sync adapter.
|
|
141
|
-
|
|
142
|
-
The `migration.up` function upgrades the database from the previous version, while the `migration.down` function rolls back the changes to the previous version.
|
|
143
|
-
|
|
144
|
-
In Alloy, migrations are defined by JavaScript files located in the `app/migrations` folder of the project. The file should be named the same as the model JavaScript file prefixed with 'YYYYMMDDHHmmss_' (datetime code followed by an underscore), for example, `20120610049877_book.js`. Alloy applies the migrations from oldest to newest, according to the datetime code at the beginning of the file name.
|
|
145
|
-
|
|
146
|
-
The migration file contains two functions that need to be implemented: `migration.up(migrator)` and `migration.down(migrator)`, where `migrator` is a special migration object that provides references to the database and table as well as some convenient functions for table operations:
|
|
147
|
-
|
|
148
|
-
| Key | Description |
|
|
149
|
-
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
-
| `db` | Handle to a `Ti.Database` instance. Use this handle to execute SQL calls using `db.execute`. DO NOT CLOSE THIS HANDLE OR OPEN A SECOND INSTANCE OF THE DATABASE. |
|
|
151
|
-
| `dbname` | Name of the database. |
|
|
152
|
-
| `table` | Name of the table. Same as value of the `config.adapter.collection_name` key. |
|
|
153
|
-
| `idAttribute` | Name of the columns attribute to use as the primary key. |
|
|
154
|
-
| `createTable` | Function to create a table. Required parameter is the `columns` object. |
|
|
155
|
-
| `dropTable` | Function to drop the current table from the database. |
|
|
156
|
-
| `insertRow` | Function to insert data into the table. Useful for preloading data. |
|
|
157
|
-
| `deleteRow` | Function to delete data from the table. |
|
|
158
|
-
|
|
159
|
-
For example, the migration file below is the initial version of the database that preloads some data in the table.
|
|
160
|
-
|
|
161
|
-
**app/migrations/20120610049877_book.js**
|
|
162
|
-
|
|
163
|
-
```javascript
|
|
164
|
-
const preload_data = [
|
|
165
|
-
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
166
|
-
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
167
|
-
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
168
|
-
{title: 'Lord of the Flies', author:'William Golding'},
|
|
169
|
-
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
170
|
-
{title: 'Animal Farm', author:'George Orwell'}
|
|
171
|
-
];
|
|
172
|
-
|
|
173
|
-
migration.up = migrator => {
|
|
18
|
+
// app/migrations/20260907120000_note.js
|
|
19
|
+
migration.up = (migrator) => {
|
|
174
20
|
migrator.createTable({
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
21
|
+
columns: {
|
|
22
|
+
id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
|
|
23
|
+
body: 'TEXT',
|
|
24
|
+
done: 'INTEGER'
|
|
179
25
|
}
|
|
180
26
|
});
|
|
181
|
-
for (let i = 0; i < preload_data.length; i++) {
|
|
182
|
-
migrator.insertRow(preload_data[i]);
|
|
183
|
-
}
|
|
184
27
|
};
|
|
185
28
|
|
|
186
|
-
migration.down = migrator => {
|
|
29
|
+
migration.down = (migrator) => {
|
|
187
30
|
migrator.dropTable();
|
|
188
31
|
};
|
|
189
32
|
```
|
|
190
33
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
Suppose later, you want to include some additional information for your books, such as an ISBN. The below migration file upgrades or rolls back the changes. Since SQLite does not support the DROP COLUMN operation, the migration needs to create a temporary table to hold the data, drop the new database, create the old database, then copy the data back. Note: if `idAttribute` is not specified, Alloy creates the `alloy_id` column and this column needs to be copied over as part of the migration.
|
|
194
|
-
|
|
195
|
-
**app/migrations/20130118069778_book.js**
|
|
196
|
-
|
|
197
|
-
```javascript
|
|
198
|
-
migration.up = migrator => {
|
|
199
|
-
migrator.db.execute('ALTER TABLE ' + migrator.table + ' ADD COLUMN isbn INT;');
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
migration.down = migrator => {
|
|
203
|
-
const db = migrator.db;
|
|
204
|
-
const table = migrator.table;
|
|
205
|
-
db.execute('CREATE TEMPORARY TABLE book_backup(title,author,alloy_id);')
|
|
206
|
-
db.execute('INSERT INTO book_backup SELECT title,author,alloy_id FROM ' + table + ';');
|
|
207
|
-
migrator.dropTable();
|
|
208
|
-
migrator.createTable({
|
|
209
|
-
columns: {
|
|
210
|
-
title:"TEXT",
|
|
211
|
-
author:"TEXT",
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
db.execute('INSERT INTO ' + table + ' SELECT title,author,alloy_id FROM book_backup;');
|
|
215
|
-
db.execute('DROP TABLE book_backup;');
|
|
216
|
-
};
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## Backbone Objects without Alloy
|
|
220
|
-
|
|
221
|
-
You can use plain Backbone Collection and Model objects in place of the Alloy versions. This does not require any special Alloy or Titanium code. Use the Backbone API to create and control Backbone objects instead of using the `createCollection` and `createModel` methods. Backbone models also do not require a model configuration file.
|
|
222
|
-
|
|
223
|
-
**app/controllers/index.js**
|
|
224
|
-
|
|
225
|
-
```javascript
|
|
226
|
-
// Initialize a collection class and implement the comparator method for sorting
|
|
227
|
-
const collection = Backbone.Collection.extend({
|
|
228
|
-
comparator(model) {
|
|
229
|
-
return model.get('title');
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
// Create a new collection
|
|
234
|
-
const library = new collection([
|
|
235
|
-
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
236
|
-
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
237
|
-
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
238
|
-
{title: 'Lord of the Flies', author:'William Golding'},
|
|
239
|
-
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
240
|
-
{title: 'Tom Sawyer', author:'Mark Twain'},
|
|
241
|
-
{title: 'Animal Farm', author:'George Orwell'}
|
|
242
|
-
]);
|
|
243
|
-
|
|
244
|
-
// Initialize a model class
|
|
245
|
-
const modelClass = Backbone.Model.extend();
|
|
246
|
-
|
|
247
|
-
// Create a new model and add it to the collection
|
|
248
|
-
const book = new modelClass({title:'Bossypants', author:'Tina Fey'});
|
|
249
|
-
library.add(book);
|
|
250
|
-
|
|
251
|
-
// Remove the very first model from the collection
|
|
252
|
-
const model = library.at(0);
|
|
253
|
-
library.remove(model);
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
These Backbone objects cannot persist to external storage without implementing the Backbone.sync method, so if you make calls to Collection.fetch, Collection.create, Model.fetch, Model.save and Model.destroy, the application throws an error.
|
|
257
|
-
|
|
258
|
-
### Using Backbone Objects with Alloy Data Binding
|
|
259
|
-
|
|
260
|
-
You can use Alloy's Model-View binding mechanism to keep the local Backbone Models and Collections in sync with an Alloy view-controller. Follow the same directions for data binding except instead of using the `Model` or `Collections` XML tag, you need to first initialize your model or collection in the alloy.js initializer file and add it to the `Alloy.Models` or `Alloy.Collections` namespace.
|
|
261
|
-
|
|
262
|
-
**app/alloy.js**
|
|
263
|
-
|
|
264
|
-
```javascript
|
|
265
|
-
// Initialize a collection class and implement the comparator method for sorting
|
|
266
|
-
const collection = Backbone.Collection.extend({
|
|
267
|
-
comparator(model) {
|
|
268
|
-
return model.get('title');
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
// Create a new collection
|
|
273
|
-
const library = new collection([
|
|
274
|
-
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
275
|
-
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
276
|
-
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
277
|
-
{title: 'Lord of the Flies', author:'William Golding'},
|
|
278
|
-
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
279
|
-
{title: 'Tom Sawyer', author:'Mark Twain'},
|
|
280
|
-
{title: 'Animal Farm', author:'George Orwell'}
|
|
281
|
-
]);
|
|
282
|
-
|
|
283
|
-
// Add the collection to the global scope
|
|
284
|
-
Alloy.Collections.book = library;
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
**app/views/index.xml**
|
|
288
|
-
|
|
289
|
-
```xml
|
|
290
|
-
<!-- Markup the view the same except there is no Collection tag -->
|
|
291
|
-
<Alloy>
|
|
292
|
-
<Window class="container">
|
|
293
|
-
<TableView dataCollection="book" dataTransform="transformFunction" dataFilter="filterFunction">
|
|
294
|
-
<TableViewRow title="{title}" />
|
|
295
|
-
</TableView>
|
|
296
|
-
</Window>
|
|
297
|
-
</Alloy>
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
**app/controllers/index.js**
|
|
301
|
-
|
|
302
|
-
```javascript
|
|
303
|
-
$.index.open();
|
|
304
|
-
|
|
305
|
-
function transformFunction(model) {
|
|
306
|
-
const transform = model.toJSON();
|
|
307
|
-
transform.title = '[' + transform.title + ']';
|
|
308
|
-
transform.custom = transform.title + " by " + transform.author;
|
|
309
|
-
return transform;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function filterFunction(collection) {
|
|
313
|
-
return collection.where({author:'Mark Twain'});
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Get a reference to the library
|
|
317
|
-
const library = Alloy.Collections.book;
|
|
318
|
-
|
|
319
|
-
// Trigger the update using the 'change' event instead of the fetch method
|
|
320
|
-
library.trigger('change');
|
|
321
|
-
|
|
322
|
-
// Initialize a model class
|
|
323
|
-
const modelClass = Backbone.Model.extend();
|
|
324
|
-
|
|
325
|
-
// Create a new model and add it to the collection
|
|
326
|
-
const book = new modelClass({title:'Bossypants', author:'Tina Fey'});
|
|
327
|
-
library.add(book);
|
|
328
|
-
|
|
329
|
-
// Remove the very first model from the collection
|
|
330
|
-
const model = library.at(0);
|
|
331
|
-
library.remove(model);
|
|
332
|
-
|
|
333
|
-
// Do not forget to call destroy to unbind the event handlers created by Alloy
|
|
334
|
-
$.index.addEventListener('close', () => {
|
|
335
|
-
$.destroy();
|
|
336
|
-
});
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
## Alloy Backbone Migration
|
|
340
|
-
|
|
341
|
-
### Overview
|
|
342
|
-
|
|
343
|
-
Alloy 1.6.0 introduces support for Backbone 1.1.2. Currently, Alloy uses Backbone 0.9.2 to support its Model and Collection objects. This guide covers the changes from Backbone 0.9.2 to 1.1.2 and the modifications you may need to update your application. Note that only changes to the Backbone Collection, Event and Model APIs are discussed in this document.
|
|
344
|
-
|
|
345
|
-
Due to breaking changes from Backbone 0.9.2 to 1.1.2, Alloy still uses Backbone 0.9.2 as its default Model and Collection implementation. You will need to update the configuration file to use the newer Backbone library.
|
|
346
|
-
|
|
347
|
-
Alloy 1.10.12 adds support for Backbone 1.3.3. However, due to breaking changes in Backbone, 0.9.2 will remain the default version.
|
|
348
|
-
|
|
349
|
-
Supported versions of Backbone for Alloy 1.10.12 are 0.9.2, 1.1.2, 1.3.3.
|
|
350
|
-
|
|
351
|
-
### Setup
|
|
352
|
-
|
|
353
|
-
To use Backbone 1.1.2 to support Alloy Model and Collections objects, open the project's `./app/config.json` file and add the `backbone` key to the to the file with the value set to `1.1.2` (or `1.3.3`). You may also set this value to `0.9.2` to force support of Backbone 0.9.2.
|
|
354
|
-
|
|
355
|
-
**app/config.json**
|
|
356
|
-
|
|
357
|
-
```json
|
|
358
|
-
{
|
|
359
|
-
"global": {},
|
|
360
|
-
"env:development": {},
|
|
361
|
-
"env:test": {},
|
|
362
|
-
"env:production": {},
|
|
363
|
-
"os:android": {},
|
|
364
|
-
"os:blackberry": {},
|
|
365
|
-
"os:ios": {},
|
|
366
|
-
"os:mobileweb": {},
|
|
367
|
-
"dependencies": {},
|
|
368
|
-
"backbone": "1.1.2"
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
### Summary of Changes
|
|
373
|
-
|
|
374
|
-
#### Collection APIs
|
|
375
|
-
|
|
376
|
-
**Fetch Method Behavior Change**: Backbone Collection objects no longer emit the `reset` event after a `fetch()` call, which means data-bound views may not update automatically. **This could break existing apps.** To use old functionality, pass `{reset: true}` when calling `fetch()` or extend the Collection class:
|
|
377
|
-
|
|
378
|
-
```javascript
|
|
379
|
-
exports.definition = {
|
|
380
|
-
config: {
|
|
381
|
-
// Model configuration
|
|
382
|
-
},
|
|
383
|
-
extendModel(Model) {
|
|
384
|
-
_.extend(Model.prototype, {
|
|
385
|
-
// extended functions and properties go here
|
|
386
|
-
});
|
|
387
|
-
return Model;
|
|
388
|
-
},
|
|
389
|
-
extendCollection(Collection) {
|
|
390
|
-
_.extend(Collection.prototype, {
|
|
391
|
-
// For Backbone v1.1.2, uncomment the following to override the
|
|
392
|
-
// fetch method to account for a breaking change in Backbone.
|
|
393
|
-
/*
|
|
394
|
-
fetch(options) {
|
|
395
|
-
options = options ? _.clone(options) : {};
|
|
396
|
-
options.reset = true;
|
|
397
|
-
return Backbone.Collection.prototype.fetch.call(this, options);
|
|
398
|
-
}
|
|
399
|
-
*/
|
|
400
|
-
});
|
|
401
|
-
return Collection;
|
|
402
|
-
}
|
|
403
|
-
};
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
**New Set Method**: To smartly update the contents of a Collection (adding new models, removing missing ones, and merging those already present), call `set()`.
|
|
407
|
-
|
|
408
|
-
**Return Value for Methods**: The return values of Collection's `add()`, `push()`, `remove()`, `reset()` and `shift()` methods return the changed model or list of models, instead of `this`.
|
|
409
|
-
|
|
410
|
-
**Add Method**: When invoking `add()` on a collection, passing `{merge: true}` will now cause duplicate models to have their attributes merged in to the existing models. To improve performance, `options.index` will no longer be set in the `add` event callback — use `collection.indexOf(model)` instead.
|
|
411
|
-
|
|
412
|
-
#### Event APIs
|
|
413
|
-
|
|
414
|
-
* All `invalid` events now pass consistent arguments. First the model in question, then the `error` object, then `options`.
|
|
415
|
-
* `Collection.sort()` now triggers a `sort` event, instead of a `reset` event.
|
|
416
|
-
* Both `sync` and `error` events within `Backbone.sync()` are now triggered regardless of the existence of success or error callbacks.
|
|
417
|
-
* While listening to a `reset` event, the list of previous models is now available in `options.previousModels`.
|
|
418
|
-
* The new Event methods `listenTo` and `stopListening` are meant for Backbone View objects. These APIs will not work with an Alloy application.
|
|
419
|
-
|
|
420
|
-
#### Model APIs
|
|
421
|
-
|
|
422
|
-
**Validation**: Model validation is now only enforced with the `save()` method. Previously, models were also validated with the `set()` method. To force validation when the `set()` method is called, pass `{validate: true}` to the method or extend the Model class. Also, validation now occurs even during 'silent' changes (passing `{silent: true}` to methods). Previously, it would not. Failed validations return the `invalid` event. Previously, a failed model validation would return the `error` event.
|
|
423
|
-
|
|
424
|
-
> **⚠️ ⚠️ Warning**
|
|
425
|
-
> To validate Model objects, implement the `validate()` method in the `extendModel` key of the model configuration file.
|
|
426
|
-
|
|
427
|
-
**Parse Method**: All `parse` methods now run after a `fetch`. You cannot change the `id` of a model during `parse`. The `parse` method receives `options` as a second parameter.
|
|
428
|
-
|
|
429
|
-
**Other Changes**:
|
|
430
|
-
|
|
431
|
-
* Calling `destroy()` on a Model will now return `false` if the model's `isNew` is set to `true`.
|
|
432
|
-
* `Model.set()` no longer accepts another model as an argument.
|
|
433
|
-
* `url` and `urlRoot` properties may now be passed as options when instantiating a new Model.
|
|
434
|
-
* If you want to maintain current models in a collection when using `fetch` the property has changed from `{add:true}` to `{remove:false}`.
|
|
435
|
-
|
|
436
|
-
### Parse Method
|
|
437
|
-
|
|
438
|
-
After fetching a model or a collection, all defined parse methods will now be run. So fetching a collection and getting back new models could cause both the collection to parse the list, and then each model to be parsed in turn, if you have both methods defined. By default, the parse method is a no-op function that directly passes the JSON response object.
|
|
439
|
-
|
|
440
|
-
You are no longer permitted to change the `id` of your model during `parse()`. Use `idAttribute` instead.
|
|
441
|
-
|
|
442
|
-
The parse function now receives the `options` dictionary as its second parameter. Previously, it would only be passed a raw `response` object.
|
|
443
|
-
|
|
444
|
-
### Silent Option
|
|
445
|
-
|
|
446
|
-
Passing `{silent:true}` to methods now suppresses the `change:attr` events, thus a data-bound view will not be updated to reflect the changes. The sql sync adapter passed this option by default. It has been updated to no longer pass that option when Backbone 1.1.2 is used (still passed with 0.9.2).
|
|
447
|
-
|
|
448
|
-
If you want the new behavior where `change` events are suppressed, you will need to pass this option or extend the Model or Collection class. The following sample code extends the Model `set()` method by forcing the silent option to true:
|
|
449
|
-
|
|
450
|
-
```javascript
|
|
451
|
-
exports.definition = {
|
|
452
|
-
config: {
|
|
453
|
-
// Model configuration
|
|
454
|
-
},
|
|
455
|
-
extendModel(Model) {
|
|
456
|
-
_.extend(Model.prototype, {
|
|
457
|
-
// Forces silent true option when the model is updated
|
|
458
|
-
set(attributes, options) {
|
|
459
|
-
options = options ? _.clone(options) : {};
|
|
460
|
-
options.silent = true;
|
|
461
|
-
return Backbone.Model.prototype.set.call(this, attributes, options);
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
return Model;
|
|
465
|
-
},
|
|
466
|
-
extendCollection(Collection) {
|
|
467
|
-
_.extend(Collection.prototype, {
|
|
468
|
-
// extended functions and properties go here
|
|
469
|
-
});
|
|
470
|
-
return Collection;
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
### API Changes
|
|
476
|
-
|
|
477
|
-
#### New APIs
|
|
478
|
-
|
|
479
|
-
The following APIs have been added between Backbone 1.1.2 and 0.9.2.
|
|
480
|
-
|
|
481
|
-
| API | Type | Notes |
|
|
482
|
-
| ----------------------------- | ------ | ------------------------------------------------------------------------ |
|
|
483
|
-
| Backbone.request | event | Fired whenever a request begins to be made to the server. |
|
|
484
|
-
| Backbone.Collection.findWhere | method | Same as `where()` but only returns the first result. |
|
|
485
|
-
| Backbone.Collection.set | method | Performs a "smart" update of the collection. |
|
|
486
|
-
| Backbone.Event.once | method | Same as `on()` except after the event is fired, the callback is removed. |
|
|
487
|
-
| Backbone.Model.invert | method | Returns a copy of the object where keys and values are switched. |
|
|
488
|
-
| Backbone.Model.keys | method | Returns an array of the object's keys. |
|
|
489
|
-
| Backbone.Model.omit | method | Returns a copy of an object without the specified keys. |
|
|
490
|
-
| Backbone.Model.pairs | method | Returns an array of `[key, value]` pairs. |
|
|
491
|
-
| Backbone.Model.pick | method | Returns a copy of an object with the specified keys. |
|
|
492
|
-
| Backbone.Model.values | method | Returns an array of the object's property values. |
|
|
34
|
+
This creates the initial table; it is not an example of adding a column to an existing table. Supply the migration that corresponds to each subsequent schema change, keeping timestamp order.
|
|
493
35
|
|
|
494
|
-
|
|
36
|
+
## Backbone configuration
|
|
495
37
|
|
|
496
|
-
|
|
38
|
+
Pin Backbone explicitly in `app/config.json` using `"backbone": "1.4.0"`. The currently published guide attributes 1.4.0 to Alloy 3.1.0, while the released Alloy 3.0.1 template already selects it. Do not infer an installed Alloy version from that sentence; check `alloy --version` and the project's actual setting.
|
|
497
39
|
|
|
498
|
-
|
|
499
|
-
| ---------------------------- | ------ | ------------------------------------------- |
|
|
500
|
-
| Backbone.Collection.getByCid | method | Pass the CID to the `get()` method instead. |
|
|
501
|
-
| Backbone.Model.change | method | |
|
|
40
|
+
Source: [models and collections](https://titaniumsdk.com/docs/alloy/models.md). Adapter and release caveats are checked against released Alloy 3.0.1.
|