用法:
1. 下载jash.js 和jash.css
2. 在页面加载jash.js 和 jash.css
3. 在页面上加这个链接:
Jash bookmarklet
然后点这个链接就可以调出shell窗口了。
有你的地方才是天堂 (抱歉,本博客模板不支持IE浏览器)
Hey Alex,
this is a slide from a presentation at the very beginning of jamal.
This is not wrong in general, but there is no dispatcher anymore. The
configuration, what controller is called, is now handled within the
body class.
A short explanation of this structure is:
- Interactions of the user are reflected in javascript events. So
bind events to the dom within the controller.
- Data is handled in the models so all XHR should go there
- The view modifies the dom
This is all convention, Jamal doesn't force you to do it like this...
Greetings,
Timo
1. C(ontroller) - 因为和用户交互的都是javascript事件,所以应该在controller里和dom绑定事件。
2. M(odel) - 在models里面是进行data处理,所以会放一些ajax逻辑,以及对本地数据库的操作(Jamal没有实现,但是因为项目需求我会集成到里面)。
3. V(iew) - 而在view里当然是对用户dom的修改。
代码1505行:
$(function(){
$j = jamal = jamal();
$j.start();
});
class="jamal {controller:'Foos',action:'index',debug:true}"一个页面对应一个controller,一个controller对应一个action。 如果想像rails一样,想写多个action,那么可以这样去模拟:
$j.c({Clients: {
index: function () {
this.new();
// or
$('.new').click(function(){
$j.current.new();
});
},
new: function() {}
}});
jamal.fn.extend(jamal.fn.m.prototype, {
createTable: function(option){
return true;
// 你可以在你的model里通过重载此方法实现你具体的方法。
},
});

This example is an extension of Stefans example, demonstrating how to create a One-to-Many relationship of a List with multiple Entry elements.
The HEAD includes jQuery and Active Record.
<html>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8″>
<meta name=“author” content=“Kristian Mandrup”>
<title>AcitveJS Tutorialtitle>
<script type=“text/javascript” src=“jquery/jquery-1.3.1.min.js”>
script>
<script type=“text/javascript” src=“aptana-activejs/latest/active_record.js”>
script>
head>
The BODY contains the main interface with a few usage instructions and buttons to execute differents parts of the tutorial functionality.
<body>
<pre>
Usage: Create Person relationship graph then Display created Person relationship graph
pre>
<button onclick=”createPersonGraph()“>
Create Person relationship graph
button>
<button onclick=”displayPersonGraph()“>
Display created Person relationship graph
button>
<button onclick=”initPersonGraph()“>
Initialize graph
button>
<br>
<br>
<br>
<div id=‘display’>
div>
The DIV called “display”, is the container where the model description is written to when the “Display…” button is clicked. jQuery finds the DIV with a certain ID and appends HTML as the model is traversed.
The script starts with an initDB() function, that initializes the database for use with Active Record. Here an adapter for the InMemory database is used for simplicity.
<script type=“text/javascript”>
// make Objects for Tables globally available (for simplicity)
var Person;
var Item;
var displayDiv;
function initDB(){
//connect ActiveRecord to In-memory Database
ActiveRecord.logging = true;
ActiveRecord.connect(ActiveRecord.Adapters.InMemory);
}
Next the Schema for the model is defined in initPersonSchema().
function initPersonSchema(){
//simple model: Persons
Person = ActiveRecord.create(‘persons’, {
person_id: ”,
mother_id: ”,
father_id: ”,
spouse_id: ”,
child_id: ”,
sibling_id: ”,
name: {
type: ’string’,
value: ‘No name’
},
age: {
type: ‘number’,
value: 30
},
isMale: {
type: ‘boolean’,
value: 1
},
});
Item = ActiveRecord.create(‘items’, {
person_id: ”,
name: ‘MyItem’
});
// when a person is deleted, his/her items are also deleted!
Item.belongsTo(Person);
Child = ActiveRecord.create(‘children’, {
person_id: ”,
child_id: ”,
});
Sibling = ActiveRecord.create(’siblings’, {
person_id: ”,
sibing_id: ”,
});
// Set up foreign key relationships
Person.hasOne(Person, {
name: ‘mother’,
foreignKey: ‘mother_id’,
dependent: false
});
Person.hasOne(Person, {
name: ‘father’,
foreignKey: ‘father_id’,
dependent: false
});
Person.hasOne(Person, {
name: ’spouse’,
foreignKey: ’spouse_id’,
dependent: false
});
Person.hasMany(Item, {
name: ‘item’,
foreignKey: ‘person_id’,
dependent: false
});
Person.hasMany(Child, {
name: ‘child’,
foreignKey: ‘person_id’,
dependent: false
});
Person.hasMany(Sibling, {
name: ’sibling’,
foreignKey: ‘person_id’,
dependent: false
});
/*
Child.hasMany(Person, {
name: ‘parent‘, foreignKey: ‘person_id’, dependent: false
});
*/
}
Then a function for creating an example instance of the person graph. Note the two add… helper functions
function createPersonGraph(){
//start using the model
// sister
var jessica = Person.create({
name: ‘Jessica’,
age: 12,
isMale: 0
});
// brother
var jack = Person.create({
name: ‘Jack’,
age: 14,
isMale: 1
});
// mother
var alice = Person.create({
name: ‘Alice’,
age: 42,
isMale: 0
});
// father
var adam = Person.create({
name: ‘Adam’,
age: 46,
isMale: 1
});
//save persons first to get a valid self.id the entries refer to
jessica.save();
jack.save();
adam.save();
alice.save();
jack.createMother(alice);
jack.createFather(adam);
jessica.createMother(alice);
jessica.createFather(adam);
adam.createSpouse(alice);
alice.createSpouse(adam);
var item1 = jack.createItem();
item1.set(‘name’, ‘Ball’);
var item2 = jack.createItem();
item2.set(‘name’, ‘Pillow’);
item1.save();
item2.save();
addChild(adam, jack);
addChild(adam, jessica);
addChild(alice, jack);
addChild(alice, jessica);
addSibling(jack, jessica);
// add reverse sibling connection too!
addSibling(jessica, jack);
}
function addChild(parent, child){
var childRel = parent.createChild();
childRel.set(‘child’, child.id);
childRel.save();
}
function addSibling(source, target){
var sibRel = source.createSibling();
sibRel.set(’sibling’, target.id);
sibRel.save();
}
Then follows some display functions.
function resetdisplay(){
displayDiv.html(‘Person graph
’);}
function displayRelationship(label, name){
displayDiv.append(‘ - ‘ + label + ‘ ’ + name + ‘
’);}
function displayPerson(person){
var gender = (person.isMale === 0) ? ‘male’ : ‘female’;
displayDiv.append(‘Person ’ + person.name + ‘ is a ‘ + person.age + ‘ year old ‘ + gender + ‘
’);
// display relationships!
displayMother(person);
displayFather(person);
displayItems(person);
displayChildren(person);
displaySiblings(person);
}
function displayPersonGraph(){
resetdisplay();
var persons = Person.find();
var items = Item.find();
console.log(‘Items:’ + items.length)
if (persons.length > 0) {
for (p = 0; p < persons.length; p++) {
var person = persons[p];
displayPerson(person);
}
}
else
console.log(‘No Persons created’);
}
function displayMother(person){
var mother = person.getMother();
if (mother) {
displayRelationship(‘Mother is’, mother.name);
}
}
function displayFather(person){
var father = person.getFather();
if (father) {
displayRelationship(‘Father is’, father.name);
}
}
function displaySpouse(person){
var spouse = person.getSpouse();
if (spouse) {
displayRelationship(‘Spouse of’, spouse.name);
}
}
function displayItems(person){
var items = person.getItemList();
for (i = 0; i < items.length; i++) {
var item = items[i];
console.log(item.name);
displayRelationship(‘Item’, item.name);
}
}
function displayChildren(person){
var children = person.getChildList();
console.log(‘Children:’ + children.length)
for (c = 0; c < children.length; c++) {
var childRel = children[c];
var child = Person.find(childRel.child);
console.log(child.name);
displayRelationship(‘Child’, child.name);
}
}
function displaySiblings(person){
var siblings = person.getSiblingList();
console.log(‘Siblings:’ + siblings.length)
for (s = 0; s < siblings.length; s++) {
var sibRel = siblings[s];
var sibling = Person.find(sibRel.sibling);
console.log(sibling.name);
displayRelationship(‘Sibling’, sibling.name);
}
}
Finally, the function that starts up the application when the document has finished loading. A reference to the display container is saved globally for reuse. The display is reset. The database is then initialized and the schema created. Population of the model and the display is all performed as a result of the user clicking the appropriate buttons.
$(document).ready(function(){
//initialy reset the display
displayDiv = $(‘div#display’);
resetdisplay();
// initialize DB and schema on load
initDB();
initPersonSchema();
});
script>
body>
html>
It took quite a lot of experimentation to get to this resulting code. I’m sure there is a better way of creating the model relationships, than using the ID properties in some cases as is done here, but the documentation is lacking in some respects.
Any comments and improvements are most welcome. I hope this is of use for newcomers to Active Record. Enjoy!
Below is another snippet from a sample I am working on. Note the getStringList() which references an AttributeString table through a reference named “string” (defined in the options object on the hasMany relationship.
function initGenericSchema(){
Attribute = ActiveRecord.create(‘attributes’, {
attribute_id: ”, // primary key
profile_id: ”, // foreign key
name: ”,
type: ”
});
// string attribute
AttributeString = ActiveRecord.create(‘attributeStrings’, {
attributeString_id: ”, // primary key
attribute_id: ”, // foreign key
type: ’string’,
val: {
type: ’string’,
value: ”
}
});
Attribute.hasMany(AttributeString, {
name: ’string’,
foreignKey: ‘attributeString_id’,
dependent: false
});
Profile = ActiveRecord.create(‘profile’, {
profile_id: ”
});
Profile.hasMany(Attribute, {
name: ‘attribute’,
foreignKey: ‘attribute_id’,
dependent: false
});
}
function createProfileGraph(){
//start using the model
// string
var strName = AttributeString.create({
val: ‘MyName’
});
strName.save();
console.log(’string:’ + strName.val + ‘, type:’ + strName.type);
// Atribute: Name
var attribName = Attribute.create({
name: ‘Firstname’,
type: ‘name’
});
var profile = Profile.create({
});
attribName.save();
profile.save();
console.log(‘attribName: ‘ + attribName.name + ‘, ‘ + attribName.type);
addAttributeString(attribName, strName);
addAttribute(profile, attribName);
console.log(‘attribName: ‘ + attribName.name + ‘, ‘ + attribName.type);
// to get Relation use name of relation (name in options obj), not name of referenced table!
var strings = attribName.getStringList();
console.log(’strings:’ + strings.length);
var str = strings[0];
console.log(’string:’ + str.val + ‘, type:’ + str.type);
}
I have had some trouble with conflicts on some sort of reserved words within A.R. One such word is “class”. The following schema causes errors, since the reserved word “class” is used in the table name and a relationship name:
function initGenericSchema(){
GObject = ActiveRecord.create(‘objects’, {
gobject_id: ”, // primary key
name: ”
});
ObjectClass = ActiveRecord.create(‘objectClasses’, {
objectClass_id: ”, // primary key
gobject_id: ”, // foreign key
name: ”
});
GObject.hasMany(ObjectClass, {
name: ‘objectClass‘,
foreignKey: ‘gobject_id’,
dependent: false
});
}
These can be fixed to the following schema, using non-conflicting names:
function initGenericSchema(){
GObject = ActiveRecord.create(‘objects’, {
gobject_id: ”, // primary key
name: ”
});
ObjectClass = ActiveRecord.create(‘objectTypes‘, {
objectClass_id: ”, // primary key
gobject_id: ”, // foreign key
name: ”
});
GObject.hasMany(ObjectClass, {
name: ‘objectType‘,
foreignKey: ‘gobject_id’,
dependent: false
});
}