@maccesar/titools 3.3.0 → 4.0.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/README.md +27 -61
- package/lib/cleanup.js +29 -0
- package/lib/commands/agents.js +8 -7
- package/lib/commands/skills.js +118 -23
- package/lib/config.js +13 -15
- package/lib/installer.js +5 -3
- package/lib/utils.js +36 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +188 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +233 -0
- package/skills/alloy-guides/references/CONCEPTS.md +171 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +279 -0
- package/skills/alloy-guides/references/MODELS.md +742 -0
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +482 -0
- package/skills/alloy-guides/references/PURGETSS.md +57 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +235 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +375 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +102 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +581 -0
- package/skills/alloy-guides/references/WIDGETS.md +160 -0
- package/skills/alloy-howtos/SKILL.md +179 -0
- package/skills/alloy-howtos/references/best_practices.md +121 -0
- package/skills/alloy-howtos/references/cli_reference.md +230 -0
- package/skills/alloy-howtos/references/config_files.md +158 -0
- package/skills/alloy-howtos/references/custom_tags.md +148 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +78 -0
- package/skills/alloy-howtos/references/samples.md +156 -0
- package/skills/purgetss/SKILL.md +6 -3
- package/skills/purgetss/references/EXAMPLES.md +8 -6
- package/skills/purgetss/references/app-branding.md +5 -0
- package/skills/purgetss/references/apply-directive.md +1 -1
- package/skills/purgetss/references/class-categories.md +1 -1
- package/skills/purgetss/references/class-index-properties.md +618 -0
- package/skills/purgetss/references/class-index.md +4 -610
- package/skills/purgetss/references/cli-commands.md +15 -0
- package/skills/purgetss/references/custom-fonts.md +39 -36
- package/skills/purgetss/references/custom-rules.md +1 -1
- package/skills/purgetss/references/customization-deep-dive.md +64 -1
- package/skills/purgetss/references/icon-fonts.md +2 -0
- package/skills/purgetss/references/migration-guide.md +53 -1
- package/skills/purgetss/references/multi-density-images.md +53 -2
- package/skills/purgetss/references/svg-pipeline.md +249 -0
- package/skills/purgetss/references/tikit-components.md +2 -2
- package/skills/purgetss/references/titanium-resets.md +2 -2
- package/skills/purgetss/references/ui-ux-design.md +7 -5
- package/skills/purgetss/references/version-history.md +12 -0
- package/skills/ti-api/SKILL.md +128 -0
- package/skills/ti-api/references/api-android.md +675 -0
- package/skills/ti-api/references/api-app-platform.md +636 -0
- package/skills/ti-api/references/api-core.md +764 -0
- package/skills/ti-api/references/api-data-network.md +641 -0
- package/skills/ti-api/references/api-media.md +655 -0
- package/skills/ti-api/references/api-modules-ble-bluetooth.md +657 -0
- package/skills/ti-api/references/api-modules-coremotion-urlsession.md +411 -0
- package/skills/ti-api/references/api-modules-map.md +632 -0
- package/skills/ti-api/references/api-modules-nfc.md +725 -0
- package/skills/ti-api/references/api-modules-social-misc.md +526 -0
- package/skills/ti-api/references/api-services.md +700 -0
- package/skills/ti-api/references/api-ui-android.md +499 -0
- package/skills/ti-api/references/api-ui-extras.md +702 -0
- package/skills/ti-api/references/api-ui-ios-animator.md +378 -0
- package/skills/ti-api/references/api-ui-ios.md +756 -0
- package/skills/ti-api/references/api-ui-lists.md +581 -0
- package/skills/ti-api/references/api-ui-text-input.md +607 -0
- package/skills/ti-api/references/api-ui-views.md +572 -0
- package/skills/ti-api/references/api-ui-windows-navigation.md +676 -0
- package/skills/ti-api/references/api-xml-global.md +743 -0
- package/skills/ti-guides/SKILL.md +82 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +155 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +373 -0
- package/skills/ti-guides/references/application-frameworks.md +366 -0
- package/skills/ti-guides/references/cli-reference.md +700 -0
- package/skills/ti-guides/references/coding-best-practices.md +150 -0
- package/skills/ti-guides/references/commonjs-advanced.md +279 -0
- package/skills/ti-guides/references/hello-world.md +99 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +458 -0
- package/skills/ti-guides/references/javascript-primer.md +402 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +172 -0
- package/skills/ti-guides/references/style-and-conventions.md +104 -0
- package/skills/ti-guides/references/tiapp-config.md +655 -0
- package/skills/ti-howtos/SKILL.md +131 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +609 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +96 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +162 -0
- package/skills/ti-howtos/references/cross-platform-development.md +358 -0
- package/skills/ti-howtos/references/debugging-profiling.md +473 -0
- package/skills/ti-howtos/references/extending-titanium.md +684 -0
- package/skills/ti-howtos/references/google-maps-v2.md +172 -0
- package/skills/ti-howtos/references/ios-map-kit.md +149 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +595 -0
- package/skills/ti-howtos/references/local-data-sources.md +310 -0
- package/skills/ti-howtos/references/location-and-maps.md +267 -0
- package/skills/ti-howtos/references/media-apis.md +268 -0
- package/skills/ti-howtos/references/notification-services.md +539 -0
- package/skills/ti-howtos/references/remote-data-sources.md +339 -0
- package/skills/ti-howtos/references/tutorials.md +552 -0
- package/skills/ti-howtos/references/using-modules.md +182 -0
- package/skills/ti-howtos/references/web-content-integration.md +288 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +125 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# Alloy Models — Advanced Topics
|
|
2
|
+
|
|
3
|
+
Persistence, custom adapters, schema migrations, plain Backbone usage, and the Backbone 0.9.2 → 1.1.2 / 1.3.3 migration. For core model and collection definition, plus data binding to views, see [MODELS.md](MODELS.md).
|
|
4
|
+
|
|
5
|
+
1. [Alloy Sync Adapters and Migrations](#alloy-sync-adapters-and-migrations)
|
|
6
|
+
2. [Backbone Objects without Alloy](#backbone-objects-without-alloy)
|
|
7
|
+
3. [Alloy Backbone Migration](#alloy-backbone-migration)
|
|
8
|
+
|
|
9
|
+
## Alloy Sync Adapters and Migrations
|
|
10
|
+
|
|
11
|
+
### Sync Adapters
|
|
12
|
+
|
|
13
|
+
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.
|
|
14
|
+
|
|
15
|
+
#### Backbone Sync
|
|
16
|
+
|
|
17
|
+
Backbone syncs your models to persistent storage devices based on the implementation of the [Backbone.sync method](https://titaniumsdk.com/guide/Alloy_Framework/Alloy_Guide/Alloy_Models/Alloy_Sync_Adapters_and_Migrations.html). 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.
|
|
18
|
+
|
|
19
|
+
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.
|
|
20
|
+
|
|
21
|
+
The sync method depends on calls to other Backbone methods as described in the table below.
|
|
22
|
+
|
|
23
|
+
| **Backbone Method** | **Sync CRUD Method** | **Equivalent HTTP Method** | **Equivalent SQL Method** |
|
|
24
|
+
| ---------------------------------------------------------------- | -------------------- | -------------------------- | ------------------------- |
|
|
25
|
+
| Collection.fetch | read | GET | SELECT |
|
|
26
|
+
| Collection.create (id == null) or Collection.create (id != null) | create or update | POST or PUT | INSERT or UPDATE |
|
|
27
|
+
| Model.fetch | read | GET | SELECT |
|
|
28
|
+
| Model.save (id == null) or Model.save (id != null) | create or update | POST or PUT | INSERT or UPDATE |
|
|
29
|
+
| Model.destroy | delete | DELETE | DELETE |
|
|
30
|
+
|
|
31
|
+
#### Ready-Made Sync Adapters
|
|
32
|
+
|
|
33
|
+
Alloy provides a few ready-made sync adapters. In the 'adapter' object, set the 'type' to use one of the following:
|
|
34
|
+
|
|
35
|
+
* `sql` for the SQLite database on the Android and iOS platform.
|
|
36
|
+
* `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.
|
|
37
|
+
* `localStorage` for HTML5 localStorage on the Mobile Web platform. Deprecated since Alloy 1.5.0. Use the `properties` adapter instead.
|
|
38
|
+
|
|
39
|
+
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.
|
|
40
|
+
|
|
41
|
+
##### SQLite Sync Adapter Features
|
|
42
|
+
|
|
43
|
+
The `sql` sync adapter has a few extra features:
|
|
44
|
+
|
|
45
|
+
**Fetch method accepts SQL Query**
|
|
46
|
+
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
const library = Alloy.createCollection('book');
|
|
51
|
+
const table = library.config.adapter.collection_name;
|
|
52
|
+
// use a simple query
|
|
53
|
+
library.fetch({query:'SELECT * from ' + table + ' where author="' + searchAuthor + '"'});
|
|
54
|
+
// or a prepared statement
|
|
55
|
+
library.fetch({query: { statement: 'SELECT * from ' + table + ' where author = ?', params: [searchAuthor] }});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Fetch method accepts ID attribute**
|
|
59
|
+
|
|
60
|
+
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:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
myModel.fetch({id: 123});
|
|
64
|
+
// is equivalent to
|
|
65
|
+
myModel.fetch({query: 'select * from ... where id = ' + 123 });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Columns accept SQLite keywords**
|
|
69
|
+
|
|
70
|
+
The columns values accept SQLite keywords, such as AUTOINCREMENT and PRIMARY KEY. For example:
|
|
71
|
+
|
|
72
|
+
**app/models/book.js**
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
exports.definition = {
|
|
76
|
+
config: {
|
|
77
|
+
"columns": {
|
|
78
|
+
"title": "TEXT",
|
|
79
|
+
"author": "TEXT",
|
|
80
|
+
"book_id": "INTEGER PRIMARY KEY AUTOINCREMENT"
|
|
81
|
+
},
|
|
82
|
+
"adapter": {
|
|
83
|
+
"type": "sql",
|
|
84
|
+
"collection_name": "books",
|
|
85
|
+
"idAttribute": "book_id"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Specify columns property as primary ID**
|
|
92
|
+
|
|
93
|
+
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.
|
|
94
|
+
|
|
95
|
+
**Specify a migration to use**
|
|
96
|
+
|
|
97
|
+
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.
|
|
98
|
+
|
|
99
|
+
**Specify a database to use**
|
|
100
|
+
|
|
101
|
+
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_`.
|
|
102
|
+
|
|
103
|
+
**Specify a database file to preload**
|
|
104
|
+
|
|
105
|
+
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.
|
|
106
|
+
|
|
107
|
+
### Custom Sync Adapters
|
|
108
|
+
|
|
109
|
+
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.
|
|
110
|
+
|
|
111
|
+
The sync adapter exports three functions:
|
|
112
|
+
|
|
113
|
+
* `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.
|
|
114
|
+
|
|
115
|
+
* `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.
|
|
116
|
+
|
|
117
|
+
* `module.exports.sync` - implement the Backbone.sync method.
|
|
118
|
+
|
|
119
|
+
### Migrations
|
|
120
|
+
|
|
121
|
+
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.
|
|
122
|
+
|
|
123
|
+
The `migration.up` function upgrades the database from the previous version, while the `migration.down` function rolls back the changes to the previous version.
|
|
124
|
+
|
|
125
|
+
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.
|
|
126
|
+
|
|
127
|
+
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:
|
|
128
|
+
|
|
129
|
+
| Key | Description |
|
|
130
|
+
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
131
|
+
| `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. |
|
|
132
|
+
| `dbname` | Name of the database. |
|
|
133
|
+
| `table` | Name of the table. Same as value of the `config.adapter.collection_name` key. |
|
|
134
|
+
| `idAttribute` | Name of the columns attribute to use as the primary key. |
|
|
135
|
+
| `createTable` | Function to create a table. Required parameter is the `columns` object. |
|
|
136
|
+
| `dropTable` | Function to drop the current table from the database. |
|
|
137
|
+
| `insertRow` | Function to insert data into the table. Useful for preloading data. |
|
|
138
|
+
| `deleteRow` | Function to delete data from the table. |
|
|
139
|
+
|
|
140
|
+
For example, the migration file below is the initial version of the database that preloads some data in the table.
|
|
141
|
+
|
|
142
|
+
**app/migrations/20120610049877_book.js**
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
const preload_data = [
|
|
146
|
+
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
147
|
+
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
148
|
+
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
149
|
+
{title: 'Lord of the Flies', author:'William Golding'},
|
|
150
|
+
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
151
|
+
{title: 'Animal Farm', author:'George Orwell'}
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
migration.up = migrator => {
|
|
155
|
+
migrator.createTable({
|
|
156
|
+
"columns":
|
|
157
|
+
{
|
|
158
|
+
"book": "TEXT",
|
|
159
|
+
"author": "TEXT"
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
for (let i = 0; i < preload_data.length; i++) {
|
|
163
|
+
migrator.insertRow(preload_data[i]);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
migration.down = migrator => {
|
|
168
|
+
migrator.dropTable();
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Migration Rollback Example
|
|
173
|
+
|
|
174
|
+
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.
|
|
175
|
+
|
|
176
|
+
**app/migrations/20130118069778_book.js**
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
migration.up = migrator => {
|
|
180
|
+
migrator.db.execute('ALTER TABLE ' + migrator.table + ' ADD COLUMN isbn INT;');
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
migration.down = migrator => {
|
|
184
|
+
const db = migrator.db;
|
|
185
|
+
const table = migrator.table;
|
|
186
|
+
db.execute('CREATE TEMPORARY TABLE book_backup(title,author,alloy_id);')
|
|
187
|
+
db.execute('INSERT INTO book_backup SELECT title,author,alloy_id FROM ' + table + ';');
|
|
188
|
+
migrator.dropTable();
|
|
189
|
+
migrator.createTable({
|
|
190
|
+
columns: {
|
|
191
|
+
title:"TEXT",
|
|
192
|
+
author:"TEXT",
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
db.execute('INSERT INTO ' + table + ' SELECT title,author,alloy_id FROM book_backup;');
|
|
196
|
+
db.execute('DROP TABLE book_backup;');
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Backbone Objects without Alloy
|
|
201
|
+
|
|
202
|
+
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.
|
|
203
|
+
|
|
204
|
+
**app/controllers/index.js**
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
// Initialize a collection class and implement the comparator method for sorting
|
|
208
|
+
const collection = Backbone.Collection.extend({
|
|
209
|
+
comparator(model) {
|
|
210
|
+
return model.get('title');
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Create a new collection
|
|
215
|
+
const library = new collection([
|
|
216
|
+
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
217
|
+
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
218
|
+
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
219
|
+
{title: 'Lord of the Flies', author:'William Golding'},
|
|
220
|
+
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
221
|
+
{title: 'Tom Sawyer', author:'Mark Twain'},
|
|
222
|
+
{title: 'Animal Farm', author:'George Orwell'}
|
|
223
|
+
]);
|
|
224
|
+
|
|
225
|
+
// Initialize a model class
|
|
226
|
+
const modelClass = Backbone.Model.extend();
|
|
227
|
+
|
|
228
|
+
// Create a new model and add it to the collection
|
|
229
|
+
const book = new modelClass({title:'Bossypants', author:'Tina Fey'});
|
|
230
|
+
library.add(book);
|
|
231
|
+
|
|
232
|
+
// Remove the very first model from the collection
|
|
233
|
+
const model = library.at(0);
|
|
234
|
+
library.remove(model);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
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.
|
|
238
|
+
|
|
239
|
+
### Using Backbone Objects with Alloy Data Binding
|
|
240
|
+
|
|
241
|
+
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.
|
|
242
|
+
|
|
243
|
+
**app/alloy.js**
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
// Initialize a collection class and implement the comparator method for sorting
|
|
247
|
+
const collection = Backbone.Collection.extend({
|
|
248
|
+
comparator(model) {
|
|
249
|
+
return model.get('title');
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Create a new collection
|
|
254
|
+
const library = new collection([
|
|
255
|
+
{title: 'To Kill a Mockingbird', author:'Harper Lee'},
|
|
256
|
+
{title: 'The Catcher in the Rye', author:'J. D. Salinger'},
|
|
257
|
+
{title: 'Of Mice and Men', author:'John Steinbeck'},
|
|
258
|
+
{title: 'Lord of the Flies', author:'William Golding'},
|
|
259
|
+
{title: 'The Great Gatsby', author:'F. Scott Fitzgerald'},
|
|
260
|
+
{title: 'Tom Sawyer', author:'Mark Twain'},
|
|
261
|
+
{title: 'Animal Farm', author:'George Orwell'}
|
|
262
|
+
]);
|
|
263
|
+
|
|
264
|
+
// Add the collection to the global scope
|
|
265
|
+
Alloy.Collections.book = library;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**app/views/index.xml**
|
|
269
|
+
|
|
270
|
+
```xml
|
|
271
|
+
<!-- Markup the view the same except there is no Collection tag -->
|
|
272
|
+
<Alloy>
|
|
273
|
+
<Window class="container">
|
|
274
|
+
<TableView dataCollection="book" dataTransform="transformFunction" dataFilter="filterFunction">
|
|
275
|
+
<TableViewRow title="{title}" />
|
|
276
|
+
</TableView>
|
|
277
|
+
</Window>
|
|
278
|
+
</Alloy>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**app/controllers/index.js**
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
$.index.open();
|
|
285
|
+
|
|
286
|
+
function transformFunction(model) {
|
|
287
|
+
const transform = model.toJSON();
|
|
288
|
+
transform.title = '[' + transform.title + ']';
|
|
289
|
+
transform.custom = transform.title + " by " + transform.author;
|
|
290
|
+
return transform;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function filterFunction(collection) {
|
|
294
|
+
return collection.where({author:'Mark Twain'});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Get a reference to the library
|
|
298
|
+
const library = Alloy.Collections.book;
|
|
299
|
+
|
|
300
|
+
// Trigger the update using the 'change' event instead of the fetch method
|
|
301
|
+
library.trigger('change');
|
|
302
|
+
|
|
303
|
+
// Initialize a model class
|
|
304
|
+
const modelClass = Backbone.Model.extend();
|
|
305
|
+
|
|
306
|
+
// Create a new model and add it to the collection
|
|
307
|
+
const book = new modelClass({title:'Bossypants', author:'Tina Fey'});
|
|
308
|
+
library.add(book);
|
|
309
|
+
|
|
310
|
+
// Remove the very first model from the collection
|
|
311
|
+
const model = library.at(0);
|
|
312
|
+
library.remove(model);
|
|
313
|
+
|
|
314
|
+
// Do not forget to call destroy to unbind the event handlers created by Alloy
|
|
315
|
+
$.index.addEventListener('close', () => {
|
|
316
|
+
$.destroy();
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Alloy Backbone Migration
|
|
321
|
+
|
|
322
|
+
### Overview
|
|
323
|
+
|
|
324
|
+
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.
|
|
325
|
+
|
|
326
|
+
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.
|
|
327
|
+
|
|
328
|
+
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.
|
|
329
|
+
|
|
330
|
+
Supported versions of Backbone for Alloy 1.10.12 are 0.9.2, 1.1.2, 1.3.3.
|
|
331
|
+
|
|
332
|
+
### Setup
|
|
333
|
+
|
|
334
|
+
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.
|
|
335
|
+
|
|
336
|
+
**app/config.json**
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"global": {},
|
|
341
|
+
"env:development": {},
|
|
342
|
+
"env:test": {},
|
|
343
|
+
"env:production": {},
|
|
344
|
+
"os:android": {},
|
|
345
|
+
"os:blackberry": {},
|
|
346
|
+
"os:ios": {},
|
|
347
|
+
"os:mobileweb": {},
|
|
348
|
+
"dependencies": {},
|
|
349
|
+
"backbone": "1.1.2"
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Summary of Changes
|
|
354
|
+
|
|
355
|
+
#### Collection APIs
|
|
356
|
+
|
|
357
|
+
**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:
|
|
358
|
+
|
|
359
|
+
```javascript
|
|
360
|
+
exports.definition = {
|
|
361
|
+
config: {
|
|
362
|
+
// Model configuration
|
|
363
|
+
},
|
|
364
|
+
extendModel(Model) {
|
|
365
|
+
_.extend(Model.prototype, {
|
|
366
|
+
// extended functions and properties go here
|
|
367
|
+
});
|
|
368
|
+
return Model;
|
|
369
|
+
},
|
|
370
|
+
extendCollection(Collection) {
|
|
371
|
+
_.extend(Collection.prototype, {
|
|
372
|
+
// For Backbone v1.1.2, uncomment the following to override the
|
|
373
|
+
// fetch method to account for a breaking change in Backbone.
|
|
374
|
+
/*
|
|
375
|
+
fetch(options) {
|
|
376
|
+
options = options ? _.clone(options) : {};
|
|
377
|
+
options.reset = true;
|
|
378
|
+
return Backbone.Collection.prototype.fetch.call(this, options);
|
|
379
|
+
}
|
|
380
|
+
*/
|
|
381
|
+
});
|
|
382
|
+
return Collection;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**New Set Method**: To smartly update the contents of a Collection (adding new models, removing missing ones, and merging those already present), call `set()`.
|
|
388
|
+
|
|
389
|
+
**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`.
|
|
390
|
+
|
|
391
|
+
**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.
|
|
392
|
+
|
|
393
|
+
#### Event APIs
|
|
394
|
+
|
|
395
|
+
* All `invalid` events now pass consistent arguments. First the model in question, then the `error` object, then `options`.
|
|
396
|
+
* `Collection.sort()` now triggers a `sort` event, instead of a `reset` event.
|
|
397
|
+
* Both `sync` and `error` events within `Backbone.sync()` are now triggered regardless of the existence of success or error callbacks.
|
|
398
|
+
* While listening to a `reset` event, the list of previous models is now available in `options.previousModels`.
|
|
399
|
+
* The new Event methods `listenTo` and `stopListening` are meant for Backbone View objects. These APIs will not work with an Alloy application.
|
|
400
|
+
|
|
401
|
+
#### Model APIs
|
|
402
|
+
|
|
403
|
+
**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.
|
|
404
|
+
|
|
405
|
+
> **⚠️ ⚠️ Warning**
|
|
406
|
+
> To validate Model objects, implement the `validate()` method in the `extendModel` key of the model configuration file.
|
|
407
|
+
|
|
408
|
+
**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.
|
|
409
|
+
|
|
410
|
+
**Other Changes**:
|
|
411
|
+
|
|
412
|
+
* Calling `destroy()` on a Model will now return `false` if the model's `isNew` is set to `true`.
|
|
413
|
+
* `Model.set()` no longer accepts another model as an argument.
|
|
414
|
+
* `url` and `urlRoot` properties may now be passed as options when instantiating a new Model.
|
|
415
|
+
* If you want to maintain current models in a collection when using `fetch` the property has changed from `{add:true}` to `{remove:false}`.
|
|
416
|
+
|
|
417
|
+
### Parse Method
|
|
418
|
+
|
|
419
|
+
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.
|
|
420
|
+
|
|
421
|
+
You are no longer permitted to change the `id` of your model during `parse()`. Use `idAttribute` instead.
|
|
422
|
+
|
|
423
|
+
The parse function now receives the `options` dictionary as its second parameter. Previously, it would only be passed a raw `response` object.
|
|
424
|
+
|
|
425
|
+
### Silent Option
|
|
426
|
+
|
|
427
|
+
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).
|
|
428
|
+
|
|
429
|
+
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:
|
|
430
|
+
|
|
431
|
+
```javascript
|
|
432
|
+
exports.definition = {
|
|
433
|
+
config: {
|
|
434
|
+
// Model configuration
|
|
435
|
+
},
|
|
436
|
+
extendModel(Model) {
|
|
437
|
+
_.extend(Model.prototype, {
|
|
438
|
+
// Forces silent true option when the model is updated
|
|
439
|
+
set(attributes, options) {
|
|
440
|
+
options = options ? _.clone(options) : {};
|
|
441
|
+
options.silent = true;
|
|
442
|
+
return Backbone.Model.prototype.set.call(this, attributes, options);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return Model;
|
|
446
|
+
},
|
|
447
|
+
extendCollection(Collection) {
|
|
448
|
+
_.extend(Collection.prototype, {
|
|
449
|
+
// extended functions and properties go here
|
|
450
|
+
});
|
|
451
|
+
return Collection;
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### API Changes
|
|
457
|
+
|
|
458
|
+
#### New APIs
|
|
459
|
+
|
|
460
|
+
The following APIs have been added between Backbone 1.1.2 and 0.9.2.
|
|
461
|
+
|
|
462
|
+
| API | Type | Notes |
|
|
463
|
+
| ----------------------------- | ------ | ------------------------------------------------------------------------ |
|
|
464
|
+
| Backbone.request | event | Fired whenever a request begins to be made to the server. |
|
|
465
|
+
| Backbone.Collection.findWhere | method | Same as `where()` but only returns the first result. |
|
|
466
|
+
| Backbone.Collection.set | method | Performs a "smart" update of the collection. |
|
|
467
|
+
| Backbone.Event.once | method | Same as `on()` except after the event is fired, the callback is removed. |
|
|
468
|
+
| Backbone.Model.invert | method | Returns a copy of the object where keys and values are switched. |
|
|
469
|
+
| Backbone.Model.keys | method | Returns an array of the object's keys. |
|
|
470
|
+
| Backbone.Model.omit | method | Returns a copy of an object without the specified keys. |
|
|
471
|
+
| Backbone.Model.pairs | method | Returns an array of `[key, value]` pairs. |
|
|
472
|
+
| Backbone.Model.pick | method | Returns a copy of an object with the specified keys. |
|
|
473
|
+
| Backbone.Model.values | method | Returns an array of the object's property values. |
|
|
474
|
+
|
|
475
|
+
#### Removed APIs
|
|
476
|
+
|
|
477
|
+
The following APIs have been removed between Backbone 1.1.2 and 0.9.2.
|
|
478
|
+
|
|
479
|
+
| API | Type | Notes |
|
|
480
|
+
| ---------------------------- | ------ | ------------------------------------------- |
|
|
481
|
+
| Backbone.Collection.getByCid | method | Pass the CID to the `get()` method instead. |
|
|
482
|
+
| Backbone.Model.change | method | |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# PurgeTSS
|
|
2
|
+
|
|
3
|
+
<!-- AUDIT-SKIP: This file is manually maintained against the PurgeTSS toolkit's own README at https://purgetss.com, NOT against `Alloy_PurgeTSS.md` upstream in `tidev/titanium-docs`. The auditor must skip this file during automated syncs. Update only when explicitly instructed. -->
|
|
4
|
+
|
|
5
|
+
> **Note for auditors and maintainers:** this reference is sourced from the PurgeTSS toolkit's own documentation at [purgetss.com](https://purgetss.com), not from the official Alloy docs page (`Alloy_PurgeTSS.md`). Do **not** auto-sync this file against `tidev/titanium-docs` — its content lives in a different upstream and only updates when the PurgeTSS toolkit ships new releases.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
PurgeTSS is a toolkit for building mobile apps with the [Titanium framework](https://titaniumsdk.com). It adds practical utilities for styling and setup work.
|
|
10
|
+
|
|
11
|
+
It includes utility classes, icon font support, an Animation module, a simple grid system, and the `shades` command for generating custom colors.
|
|
12
|
+
|
|
13
|
+
If you build UI-heavy screens, PurgeTSS keeps you from hand-writing long TSS files.
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
- 23,300+ utility classes for colors, spacing, typography, layout, and more.
|
|
18
|
+
- Parses XML files and writes an `app.tss` with only the classes you use.
|
|
19
|
+
- Customizable through `config.cjs`, with arbitrary values for one-off sizes and colors.
|
|
20
|
+
- Icon fonts for Buttons and Labels: Font Awesome, Material Icons, Material Symbols, and Framework7-Icons.
|
|
21
|
+
- `build-fonts` command generates `fonts.tss` with class definitions and `fontFamily` selectors for any font you drop in.
|
|
22
|
+
- `shades` command generates color palettes from a hex value.
|
|
23
|
+
- Animation module with 2D transforms, draggable views with collision detection, sequential animations, and position utilities.
|
|
24
|
+
- Grid system for aligning and distributing elements in rows and columns.
|
|
25
|
+
|
|
26
|
+
## Table of Contents
|
|
27
|
+
|
|
28
|
+
- [Installation](https://purgetss.com/docs/Installation.md)
|
|
29
|
+
- [Commands](https://purgetss.com/docs/Commands.md)
|
|
30
|
+
- App Assets
|
|
31
|
+
- [App icons and branding](https://purgetss.com/docs/app-assets/1-app-icons-and-branding.md)
|
|
32
|
+
- [Multi-density images](https://purgetss.com/docs/app-assets/2-multi-density-images.md)
|
|
33
|
+
- Customization
|
|
34
|
+
- [The Config File](https://purgetss.com/docs/customization/1-configuring-guide.md)
|
|
35
|
+
- [Custom Rules](https://purgetss.com/docs/customization/2-custom-rules.md)
|
|
36
|
+
- [The `apply` Directive](https://purgetss.com/docs/customization/3-the-apply-directive.md)
|
|
37
|
+
- [The `opacity` Modifier](https://purgetss.com/docs/customization/4-Opacity.md)
|
|
38
|
+
- [Arbitrary Values](https://purgetss.com/docs/customization/5-arbitrary-values.md)
|
|
39
|
+
- [Platform and Device Modifiers](https://purgetss.com/docs/customization/6-platform-and-device-modifiers.md)
|
|
40
|
+
- [Icon Fonts Libraries](https://purgetss.com/docs/customization/7-icon-fonts-libraries.md)
|
|
41
|
+
- The UI Module
|
|
42
|
+
- [Introduction](https://purgetss.com/docs/purgetss-ui/1-introduction.md)
|
|
43
|
+
- [The `play` Method](https://purgetss.com/docs/purgetss-ui/2-the-play-method.md)
|
|
44
|
+
- [The `apply` Method](https://purgetss.com/docs/purgetss-ui/3-the-apply-method.md)
|
|
45
|
+
- [The `open` and `close` Methods](https://purgetss.com/docs/purgetss-ui/4-the-open-close-methods.md)
|
|
46
|
+
- [The `draggable` Method](https://purgetss.com/docs/purgetss-ui/5-the-draggable-method.md)
|
|
47
|
+
- [Complex UI Elements](https://purgetss.com/docs/purgetss-ui/7-complex-ui-elements.md)
|
|
48
|
+
- [Additional Methods](https://purgetss.com/docs/purgetss-ui/6-additional-methods.md)
|
|
49
|
+
- [Available Utilities](https://purgetss.com/docs/purgetss-ui/8-available-utilities.md)
|
|
50
|
+
- [Implementation Rules](https://purgetss.com/docs/purgetss-ui/9-implementation-rules.md)
|
|
51
|
+
- [Appearance](https://purgetss.com/docs/purgetss-ui/10-appearance.md)
|
|
52
|
+
- Best Practices
|
|
53
|
+
- [Appearance Setup](https://purgetss.com/docs/best-practices/1-appearance-setup.md)
|
|
54
|
+
- [Semantic Colors](https://purgetss.com/docs/best-practices/2-semantic-colors.md)
|
|
55
|
+
- [Large Titles on iOS](https://purgetss.com/docs/best-practices/3-large-titles-on-ios.md)
|
|
56
|
+
- [Values and Units](https://purgetss.com/docs/best-practices/4-values-and-units.md)
|
|
57
|
+
- [Grid System](https://purgetss.com/docs/grid-system.md)
|