Alternate names
Ext.data.BelongsToAssociationHierarchy
Ext.BaseExt.data.association.AssociationExt.data.association.BelongsToFiles
Represents a many to one association with another model. The owner model is expected to have a foreign key which references the primary key of the associated model:
Ext.define('Category', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
]
}
});
Ext.define('Product', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'category_id', type: 'int' },
{ name: 'name', type: 'string' }
],
// we can use the belongsTo shortcut on the model to create a belongsTo association
associations: { type: 'belongsTo', model: 'Category' }
}
});
In the example above we have created models for Products and Categories, and linked them together by saying that each Product belongs to a Category. This automatically links each Product to a Category based on the Product's category_id, and provides new functions on the Product model:
The first function that is added to the owner model is a getter function:
var product = new Product({
id: 100,
category_id: 20,
name: 'Sneakers'
});
product.getCategory(function(category, operation) {
// do something with the category object
alert(category.get('id')); // alerts 20
}, this);
The getCategory function was created on the Product model when we defined the association. This uses the Category's configured proxy to load the Category asynchronously, calling the provided callback when it has loaded.
The new getCategory function will also accept an object containing success, failure and callback properties - callback will always be called, success will only be called if the associated model was loaded successfully and failure will only be called if the associated model could not be loaded:
product.getCategory({
reload: true, // force a reload if the owner model is already cached
callback: function(category, operation) {}, // a function that will always be called
success : function(category, operation) {}, // a function that will only be called if the load succeeded
failure : function(category, operation) {}, // a function that will only be called if the load did not succeed
scope : this // optionally pass in a scope object to execute the callbacks in
});
In each case above the callbacks are called with two arguments - the associated model instance and the operation object that was executed to load that instance. The Operation object is useful when the instance could not be loaded.
Once the getter has been called on the model, it will be cached if the getter is called a second time. To force the model to reload, specify reload: true in the options object.
The second generated function sets the associated model instance - if only a single argument is passed to the setter then the following two calls are identical:
// this call...
product.setCategory(10);
// is equivalent to this call:
product.set('category_id', 10);
An instance of the owner model can also be passed as a parameter.
If we pass in a second argument, the model will be automatically saved and the second argument passed to the owner model's save method:
product.setCategory(10, function(product, operation) {
// the product has been saved
alert(product.get('category_id')); //now alerts 10
});
//alternative syntax:
product.setCategory(10, {
callback: function(product, operation) {}, // a function that will always be called
success : function(product, operation) {}, // a function that will only be called if the load succeeded
failure : function(product, operation) {}, // a function that will only be called if the load did not succeed
scope : this //optionally pass in a scope object to execute the callbacks in
});
Associations reflect on the models they are linking to automatically set up properties such as the primaryKey and foreignKey. These can alternatively be specified:
Ext.define('Product', {
extend: 'Ext.data.Model',
config: {
fields: [
// ...
],
associations: [
{ type: 'belongsTo', model: 'Category', primaryKey: 'unique_id', foreignKey: 'cat_id' }
]
}
});
Here we replaced the default primary key (defaults to 'id') and foreign key (calculated as 'category_id') with our own settings. Usually this will not be needed.
The full class name or reference to the class that the ownerModel is being associated with. This is a required configuration on every association.
The name for the associated model. This defaults to the last part of the class name of the associatedModel.
The name of the property in the data to read the association from. Defaults to the associatedName plus '_id'.
The name of the foreign key on the owner model that links it to the associated model. Defaults to the lowercased name of the associated model plus "_id", e.g. an association with a model called Product would set up a product_id foreign key.
Ext.define('Order', {
extend: 'Ext.data.Model',
fields: ['id', 'date'],
hasMany: 'Product'
});
Ext.define('Product', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'order_id'], // refers to the id of the order that this product belongs to
belongsTo: 'Group'
});
var product = new Product({
id: 1,
name: 'Product 1',
order_id: 22
}, 1);
product.getOrder(); // Will make a call to the server asking for order_id 22
The name of the getter function that will be added to the local model's prototype. Defaults to 'get' + the name of the foreign model, e.g. getCategory
The name for the owner model. This defaults to the last part of the class name of the ownerModel.
The name of the primary key on the associated model. In general this will be the Ext.data.Model.idProperty of the Model.
Defaults to: 'id'
Get the reference to the current class from which this object was instantiated. Unlike statics,
this.self
is scope-dependent and it's meant to be used for dynamic inheritance. See statics
for a detailed comparison
Ext.define('My.Cat', {
statics: {
speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
},
constructor: function() {
alert(this.self.speciesName); // dependent on 'this'
},
clone: function() {
return new this.self();
}
});
Ext.define('My.SnowLeopard', {
extend: 'My.Cat',
statics: {
speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
}
});
var cat = new My.Cat(); // alerts 'Cat'
var snowLeopard = new My.SnowLeopard(); // alerts 'Snow Leopard'
var clone = snowLeopard.clone();
alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
Call the original method that was previously overridden with override,
This method is deprecated as callParent does the same thing.
Ext.define('My.Cat', {
constructor: function() {
alert("I'm a cat!");
}
});
My.Cat.override({
constructor: function() {
alert("I'm going to be a cat!");
var instance = this.callOverridden();
alert("Meeeeoooowwww");
return instance;
}
});
var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
// alerts "I'm a cat!"
// alerts "Meeeeoooowwww"
The arguments, either an array or the arguments
object
from the current method, for example: this.callOverridden(arguments)
Returns the result of calling the overridden method
Call the "parent" method of the current method. That is the method previously overridden by derivation or by an override (see Ext.define).
Ext.define('My.Base', {
constructor: function (x) {
this.x = x;
},
statics: {
method: function (x) {
return x;
}
}
});
Ext.define('My.Derived', {
extend: 'My.Base',
constructor: function () {
this.callParent([21]);
}
});
var obj = new My.Derived();
alert(obj.x); // alerts 21
This can be used with an override as follows:
Ext.define('My.DerivedOverride', {
override: 'My.Derived',
constructor: function (x) {
this.callParent([x*2]); // calls original My.Derived constructor
}
});
var obj = new My.Derived();
alert(obj.x); // now alerts 42
This also works with static methods.
Ext.define('My.Derived2', {
extend: 'My.Base',
statics: {
method: function (x) {
return this.callParent([x*2]); // calls My.Base.method
}
}
});
alert(My.Base.method(10)); // alerts 10
alert(My.Derived2.method(10)); // alerts 20
Lastly, it also works with overridden static methods.
Ext.define('My.Derived2Override', {
override: 'My.Derived2',
statics: {
method: function (x) {
return this.callParent([x*2]); // calls My.Derived2.method
}
}
});
alert(My.Derived2.method(10)); // now alerts 40
To override a method and replace it and also call the superclass method, use callSuper. This is often done to patch a method to fix a bug.
The arguments, either an array or the arguments
object
from the current method, for example: this.callParent(arguments)
Returns the result of calling the parent method
This method is used by an override to call the superclass method but bypass any overridden method. This is often done to "patch" a method that contains a bug but for whatever reason cannot be fixed directly.
Consider:
Ext.define('Ext.some.Class', {
method: function () {
console.log('Good');
}
});
Ext.define('Ext.some.DerivedClass', {
method: function () {
console.log('Bad');
// ... logic but with a bug ...
this.callParent();
}
});
To patch the bug in DerivedClass.method
, the typical solution is to create an
override:
Ext.define('App.paches.DerivedClass', {
override: 'Ext.some.DerivedClass',
method: function () {
console.log('Fixed');
// ... logic but with bug fixed ...
this.callSuper();
}
});
The patch method cannot use callParent
to call the superclass method
since
that would call the overridden method containing the bug. In other words, the
above patch would only produce "Fixed" then "Good" in the console log, whereas,
using callParent
would produce "Fixed" then "Bad" then "Good".
The arguments, either an array or the arguments
object
from the current method, for example: this.callSuper(arguments)
Returns the result of calling the superclass method
Returns a getter function to be placed on the owner model's prototype. We cache the loaded instance the first time it is loaded so that subsequent calls to the getter always receive the same reference.
The getter function
Returns a setter function to be placed on the owner model's prototype
The setter function
Initialize configuration for this class. a typical example:
Ext.define('My.awesome.Class', {
// The default config
config: {
name: 'Awesome',
isAwesome: true
},
constructor: function(config) {
this.initConfig(config);
}
});
var awesome = new My.awesome.Class({
name: 'Super Awesome'
});
alert(awesome.getName()); // 'Super Awesome'
mixins The mixin prototypes as key - value pairs
Read associated data
The record we're writing to
The reader for the associated model
The raw associated data
Get the reference to the class from which this object was instantiated. Note that unlike self,
this.statics()
is scope-independent and it always returns the class from which it was called, regardless of what
this
points to during run-time
Ext.define('My.Cat', {
statics: {
totalCreated: 0,
speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
},
constructor: function() {
var statics = this.statics();
alert(statics.speciesName); // always equals to 'Cat' no matter what 'this' refers to
// equivalent to: My.Cat.speciesName
alert(this.self.speciesName); // dependent on 'this'
statics.totalCreated++;
},
clone: function() {
var cloned = new this.self(); // dependent on 'this'
cloned.groupName = this.statics().speciesName; // equivalent to: My.Cat.speciesName
return cloned;
}
});
Ext.define('My.SnowLeopard', {
extend: 'My.Cat',
statics: {
speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
},
constructor: function() {
this.callParent();
}
});
var cat = new My.Cat(); // alerts 'Cat', then alerts 'Cat'
var snowLeopard = new My.SnowLeopard(); // alerts 'Cat', then alerts 'Snow Leopard'
var clone = snowLeopard.clone();
alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
alert(clone.groupName); // alerts 'Cat'
alert(My.Cat.totalCreated); // alerts 3
Add methods / properties to the prototype of this class.
Ext.define('My.awesome.Cat', {
constructor: function() {
// ...
}
});
My.awesome.Cat.addMembers({
meow: function() {
alert('Meowww...');
}
});
var kitty = new My.awesome.Cat();
kitty.meow();
Add / override static properties of this class.
Ext.define('My.cool.Class', {
// this.se
});
My.cool.Class.addStatics({
someProperty: 'someValue', // My.cool.Class.someProperty = 'someValue'
method1: function() { }, // My.cool.Class.method1 = function() { ... };
method2: function() { } // My.cool.Class.method2 = function() { ... };
});
this
Borrow another class' members to the prototype of this class.
Ext.define('Bank', {
money: '$$$',
printMoney: function() {
alert('$$$$$$$');
}
});
Ext.define('Thief', {
// ...
});
Thief.borrow(Bank, ['money', 'printMoney']);
var steve = new Thief();
alert(steve.money); // alerts '$$$'
steve.printMoney(); // alerts '$$$$$$$'
The class to borrow members from
The names of the members to borrow
this
Create aliases for existing prototype methods. Example:
Ext.define('My.cool.Class', {
method1: function() { },
method2: function() { }
});
var test = new My.cool.Class();
My.cool.Class.createAlias({
method3: 'method1',
method4: 'method2'
});
test.method3(); // test.method1()
My.cool.Class.createAlias('method5', 'method3');
test.method5(); // test.method3() -> test.method1()
The new method name, or an object to set multiple aliases. See flexSetter
The original method name
Get the current class' name in string format.
Ext.define('My.cool.Class', {
constructor: function() {
alert(this.self.getName()); // alerts 'My.cool.Class'
}
});
My.cool.Class.getName(); // 'My.cool.Class'
className
Override members of this class. Overridden methods can be invoked via callParent.
Ext.define('My.Cat', {
constructor: function() {
alert("I'm a cat!");
}
});
My.Cat.override({
constructor: function() {
alert("I'm going to be a cat!");
var instance = this.callParent(arguments);
alert("Meeeeoooowwww");
return instance;
}
});
var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
// alerts "I'm a cat!"
// alerts "Meeeeoooowwww"
As of 2.1, direct use of this method is deprecated. Use Ext.define instead:
Ext.define('My.CatOverride', {
override: 'My.Cat',
constructor: function() {
alert("I'm going to be a cat!");
var instance = this.callParent(arguments);
alert("Meeeeoooowwww");
return instance;
}
});
The above accomplishes the same result but can be managed by the Ext.Loader which can properly order the override and its target class and the build process can determine whether the override is needed based on the required state of the target class (My.Cat).
This method has been deprecated since 2.1.0
Please use Ext.define instead
The properties to add to this class. This should be specified as an object literal containing one or more properties.
this class