Då var vi på det sista steget innan det är dags att implementera Todo applikationen.
Innehåll
- Filstruktur
- Moduler (AMD)
- Laddning av moduler (Require.js)
Då var det dags att bestämma hur filstrukturen i applikationen är tänkt att se ut. Egentligen så tycker jag inte att man behöver fundera speciellt mycket kring det här, huvudsaken tycker jag är att man bara delar upp de olika delarna av applikationen till passande mappar och filer. Figur 1 visar en liten illustration av hur jag har valt att dela upp min filstruktur.
Todo
| docs
| |
| | // Documentation
|
| js
| |
| |-- collections
| | | // collection modules.
| |
| |-- lib
| | | // javascript libs
| |
| |-- models
| | | // model modules
| |
| |-- views
| | | // views
| |
| |// app.js // main router
|
|-- index.html
Jag har under morgonen nu suttit och läst igenom Writing modular javascript av Addy Osmani och försökt förstå hur man bäst kan uppnå loose coupling mellan de javascript moduler jag kommer att använda.
Vad jag kan läsa mig till, och förstå, så är AMD ett rekommenderat mönster för att skapa moduler där man kan definera beroenden (dependencies) och tillsammans med en script loader (t.ex. RequireJS eller curl.js) kan erbjuda dynamisk laddning av resurser (läs scripts). Läs mer min tänkta implementation av require.js.
Mönstret verkar ganska straight forward faktiskt, man använder define() för att definera en modul, innuti define så skapara du bara ett singelton objekt med alla dina funktioner som den här modulen ska ha och längst ner returnerar du singelton objektet.
Exempel på en modul
1
2
3
4
5
6
7
8
9
10
| define(
var myModule = {
doStuff : function() {
// Do something here.
}
}
return myModule;
); |
As clean and easy as that. Exemplet ovan är ett väldigt enkelt exempel som bara definerar en modul, men man kan även ange beroenden som Addi går igenom i sin artikel.
Exempel på en modul i Backbone
Här har jag försökt, efter att ha läst Addis artikel, försökt ge mig på att definera en modul enligt AMD som använder Backbone. Modulen är en model baserad på Task objektet som finns beskrivet här.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| define(
var TaskModel = Backbone.RelationalModel.extends({
// Define the relations of the object using relational.
relations : [
{
type : Backbone.HasOne,
key : 'userId',
relatedModel : 'User',
includeInJSON : Backbone.Model.prototype.idAttribute,
collectionType : 'UserCollection'
},
{
type : Backbone.HasOne,
key : 'categoryId',
relatedModel : 'Category',
includeInJSON : Backbone.Model.prototype.idAttribute,
collectionType : 'CategoryCollection'
}
],
defaults : {
taskId : null,
content : null,
time : null,
completed : false,
userId : null,
categoryId : null
},
initialize : function() {
// Empty function for future need.
},
/**
* @param {Array} attrs The attributes to validate.
* @returns {String} If something does not validate, return string
* (throw error in backbone.) does not run set or save on model.
*/
validate : function( attrs ) {
if ( attrs.taskId === null || attrs.content === null ||
attrs.time === null || attrs.completed === null ||
attrs.userId === null || attrs.categoryId === null ) {
return "The task object does not validate.";
}
}
})
return TaskModel;
); |
Jag förstår nu hur jag ska använda mig utav Require.js för att ladda in filerna vid behov vid körning av applikationen.
För att använda Require.js för att ladda in applikationen efter att Require.js är laddat, så använder man ett speciellt attribut på script-taggen som ser ut så här:
1
| <script data-main="scripts/main" src="scripts/require.js"></script> |
data-main attributet säger åt Require.js ska ladda filen main.js som finns i scripts katalogen i applikations katalogen efter att Require.js har laddats färdigt.
Sen är det bara att fortsätta och deklarera behov i resten av applikationen genom att använda sig utav Require.js API