On the client, we use CanJS to manage our models.
In the process of creating our Models using our appdev tools, we have generated two client side Model files:
model/[modelName].jsmodel/base/[modelName].js
For this example lets assume that
- you created a new plugin named
opstool-emailNotification:appdev opstoolplugin opstool-emailNotification - you created a new model named
ENRecipient:appdev resource opstools/EmailNotification ENRecipient title:string recipients:text
In our plugin we now have an assets/opstools/EmailNotification directory created. This is our [clientRoot].
Our client side application is divided up into it's MVC components like:
[clientRoot]/controllers[clientRoot]/models[clientRoot]/models/base[clientRoot]/views
Our model's Base definition is intended to be updated by our appdev tools. As such, it is possible that the contents of this file might be regenerated by one of the appdev commands. So ... DON'T PUT YOUR CODE IN THIS FILE!
You have been warned.
When our appdev tools create a model definition for you, the models/base/ definition pre defines most of the basic information for your model. Our ENRecipient example would look like:
steal(
'appdev'
).then( function(){
// Namespacing conventions:
// AD.Model.Base.extend("[application].[Model]" , { static }, {instance} ); --> Object
AD.Model.Base.extend("opstools.EmailNotifications.ENRecipient", {
findAll: 'GET /opstool-emailNotifications/enrecipient',
findOne: 'GET /opstool-emailNotifications/enrecipient/{id}',
create: 'POST /opstool-emailNotifications/enrecipient',
update: 'PUT /opstool-emailNotifications/enrecipient/{id}',
destroy: 'DELETE /opstool-emailNotifications/destroy/{id}',
describe: function() {
return {
"title": "string",
"recipients": "text"
};
},
// associations:['actions', 'permissions'],
// multilingualFields:['role_label', 'role_description'],
// validations: {
// "role_label" : [ 'notEmpty' ],
// "role_description" : [ 'notEmpty' ]
// },
fieldId:'id',
fieldLabel:'title'
},{
// model: function() {
// return AD.Model.get('opstools.EmailNotifications.ENRecipient');
// },
// getID: function() {
// return this.attr(this.model().fieldId) || 'unknown id field';
// },
// getLabel: function() {
// return this.attr(this.model().fieldLabel) || 'unknown label field';
// }
});
});NOTE: our appdev client side framework
ADprovides a command to create a base model:AD.Model.Base.extend("[ModelName]", {static def}, {instance def})
The CanJS model implementation needs to know the URL's for the standard model actions:
findAll: 'GET /opstool-emailNotifications/enrecipient',
findOne: 'GET /opstool-emailNotifications/enrecipient/{id}',
create: 'POST /opstool-emailNotifications/enrecipient',
update: 'PUT /opstool-emailNotifications/enrecipient/{id}',
destroy: 'DELETE /opstool-emailNotifications/destroy/{id}',Our AD model implementation provides a describe() function to return the expected data types of the model's properties:
describe: function() {
return {
"title": "string",
"recipients": "text"
};
},There are some additional (optional) settings as well:
associations: which fields actually contains associated ModelsmultilingualFields: which of the field data is considered multilingualvalidations: a field_name => array hash of validations for each field in this model
The AD.Models.Base.extend() command also provides each instance of the Model with several methods:
model(): return the Model Class for this instancegetID(): return the value of the primary ID for this instancegetLabel(): return the value of the field that should be considered the label entry for this instance.
This is the model definition file that you are expected to work with. None of the appdev tools will attempt to edit this file, so you can be safe with adding your business logic to this file.
Our example ENRecipient model would look like:
steal(
'appdev',
'optools/Test/models/base/Test.js'
).then( function(){
// Namespacing conventions:
// AD.Model.extend('[application].[Model]', {static}, {instance} ); --> Object
AD.Model.extend('optools.Test.Test', {
/*
findAll: 'GET opstool-emailNotifications/enrecipient',
findOne: 'GET /opstool-emailNotifications/enrecipient/{id}',
create: 'POST /opstool-emailNotifications/enrecipient',
update: 'PUT /opstool-emailNotifications/enrecipient/{id}',
destroy: 'DELETE /opstool-emailNotifications/enrecipient/{id}',
describe: function() {}, // returns an object describing the Model definition
fieldId: 'id', // which field is the ID
fieldLabel:'title' // which field is considered the Label
*/
},{
/*
// Already Defined:
model: function() {}, // returns the Model Class for an instance
getID: function() {}, // returns the unique ID of this row
getLabel: function() {} // returns the defined label value
*/
});
});You can use this file to override any of the appdev generated defaults or add any new business logic for your model.