can.define(prototype, propDefinitions)can.DefineMap.extend([name,] [static,] prototype)new can.DefineMap([props])new can.DefineList([items])map.item(index, [newVal])map.items()list.each( callback(item, index) )list.forEach(callback[, thisArg])list.splice(index[, howMany[, ...newElements]])list.replace(collection)list.push(...elements)list.unshift(...elements)list.pop()list.shift()list.indexOf(item)list.join(separator)list.reverse()list.slice([start[, end]])list.concat(...args)
Define observable properties, type conversion, and getter/setter logic to your constructor prototypes.
var Person = function(first, last){
this.first = first;
this.last = last;
};
can.define(Person.prototype,{
first: {
type: "string"
},
last: {
type: "string"
},
fullName: {
get: function(){
return this.first+" "+this.last;
}
}
});-
prototype
{Object}: The prototype object of a constructor function. -
propDefinitions
{Object<String,propDefinition>}: An object of properties and their definitions.
Defines the type, initial value, and get, set, and serialize behavior for an observable property.
-
value
{function|*}: Specifies the initial value of the property or a function that returns the initial value.// A default age of `0`: var Person = DefineMap.extend({ age: {value: 0} }); new Person().age //-> 0
Objecttypes should not be specified directly onvaluebecause that same object will be shared on every instance of the Map. Instead, a function that returns a fresh copy should be provided:// A default address object: var Person = DefineMap.extend({ address: { value: function(){ return {city: "Chicago", state: "IL"}; }; } }); new Person().address //-> {city: "Chicago", state: "IL"};
-
Value
{function}: Specifies a function that will be called withnewwhose result is set as the initial value of the attribute.// A default empty DefineList of hobbies: var Person = DefineMap.extend({ hobbies: {Value: DefineList} }); new Person().hobbies //-> []
-
type
{function|String}: Specifies the type of the property. The type can be specified as either a function that returns the type coerced value or one of the types names.var Person = DefineMap.extend({ age: {type: "number"}, hobbies: { type: function(newValue){ if(typeof newValue === "string") { return newValue.split(",") } else if( Array.isArray(newValue) ) { return newValue; } } } }); var me = new Person({age: "33", hobbies: "bball,js"}) me.age //-> 33 me.hobbies //-> ["bball","js"]
-
Type
{function}: A constructor function that takes the value passed to [can.Map::attr attr] as the first argument and called with new. For example, if you want whatever gets passed to go throughnew Array(newValue)you can do that like:define: { items: { Type: Array } }
If the value passed to [can.Map::attr attr] is already an Array, it will be left as is.
-
set
{can.Map.prototype.define.set}: A set function that specifies what should happen when an attribute is set on a [can.Map].setis called with the result oftypeorType. The following defines apagesetter that updates the map's offset:define: { page: { set: function(newVal){ this.attr('offset', (parseInt(newVal) - 1) * this.attr('limit')); } } }
-
get
{get(lastSetValue)}: A function that specifies how the value is retrieved. The get function is converted to an [can.compute.async async compute]. It should derive its value from other values on the map. The following defines apagegetter that reads from a map's offset and limit:define: { page: { get: function (newVal) { return Math.floor(this.attr('offset') / this.attr('limit')) + 1; } } }
A
getdefinition makes the property computed which means it will not be serialized by default. -
serialize
{can.Map.prototype.define.serialize|Boolean}: Specifies the behavior of the property when [can.Map::serialize serialize] is called.By default, serialize does not include computed values. Properties with a
getdefinition are computed and therefore are not added to the result. Non-computed properties values are serialized if possible and added to the result.Paginate = can.Map.extend({ define: { pageNum: { get: function(){ return this.offset() / 20 } } } }); p = new Paginate({offset: 40}); p.serialize() //-> {offset: 40}
If
trueis specified, computed properties will be serialized and added to the result.Paginate = can.Map.extend({ define: { pageNum: { get: function(){ return this.offset() / 20 }, serialize: true } } }); p = new Paginate({offset: 40}); p.serialize() //-> {offset: 40, pageNum: 2}
If
falseis specified, non-computed properties will not be added to the result.Paginate = can.Map.extend({ define: { offset: { serialize: false } } }); p = new Paginate({offset: 40}); p.serialize() //-> {}
If a [can.Map.prototype.define.serialize serialize function] is specified, the result of the function is added to the result.
Paginate = can.Map.extend({ define: { offset: { serialize: function(offset){ return (offset / 20)+1 } } } }); p = new Paginate({offset: 40}); p.serialize() //-> {offset: 3}
Defines the type, initial value, and get, set, and serialize behavior for an
observable property. All type converters leave null and undefined as is except for
the "boolean" type converter.
- observable
{function}: The default type behavior. It converts plain Objects to DefineMaps and plain Arrays to DefineLists. Everything else is left as is. - any
{function}: Leaves the set value as is, performs no type conversion. Aliased as*. - string
{function}: Converts to a string with""+val. - date
{function}: Converts to a JavaScript date usingDate.parse(val)if a string is given ornew Date(val)if a number is passed. - number
{function}: Converts to a number with+(val). - boolean
{function}: Converts tofalseifvalis falsey,"0", or"false"; otherwise, converts totrue. - htmlbool
{function}: Likeboolean, but converts totrueif empty string ("") is passed. - compute
{function}: Allows computes to be passed and the property take on the value of the compute. - stringOrObservable
{function}: Converts plain Objects to DefineMaps, plain Arrays to DefineLists and everything else to strings. This is useful for routing.
Extends can.DefineMap, or constructor functions derived from can.DefineMap, to create a new constructor function.
var Person = can.DefineMap.extend(
"Person",
{seal: true},
{
first: "string",
last: {type: "string"},
fullName: {
get: function(){
return this.first+" "+this.last;
}
},
age: {value: 0},
});
var me = new Person({first: "Justin", last: "Meyer"})
me.fullName //-> "Justin Meyer"
me.age //-> 0-
name
{String}: Provides an optional name for this type that will show up nicely in debuggers. -
static
{Object}: Static properties that are set directly on the constructor function. -
prototype
{Object<String,function|String|types|propDefinition>}: A definition of the properties or methods on this type.
If the property definition is a plain function, it's considered a method.
var Person = DefineMap.extend({
sayHi: function(){ console.log("hi"); }
});
var me = new Person();
me.sayHi();If the property definition is a string, it's considered a type setting to be looked up in can.define.types.
var Person = DefineMap.extend({
age: 'number',
isCool: 'boolean',
hobbies: 'observable'
});
var me = new Person({age: '33', isCool: 'false', hobbies: ['js','bball']});
me.age //-> 33
me.isCool //-> false
me.hobbies instanceof DefineList //-> trueIf the property definition is a Constructor function, it's considered a Type setting.
var Address = DefineMap.extend({
zip: 'number'
});
var Person = DefineMap.extend({
address: Address
});
var me = new Person({address: {zip: '60048'}});
me.address.zip //-> 60048If the property is an object, it's considered to be a propDefinition.
var Person = DefineMap.extend({
fullName: {
get: function() {
return this.first+" "+this.last;
},
set: function(newVal) {
var parts = newVal.split(" ");
this.first = parts[0];
this.last = parts[1];
}
},
// slick way of creating an 'inline' type.
address: {
Type: {
zip: "number"
}
}
});
var me = new Person({fullName: "Rami Myer", address: {zip: '60048'}});
me.first //-> "Rami"
me.address.zip //-> 60048- returns
{can-define/map}: A DefineMap constructor function.
Defines if instances of the map should be sealed in development.
If true, in development, instances of this object will be sealed. In strict mode errors will be thrown when undefined properties are set. This is the default
behavior of extended DefineMaps:
"use strict";
var Person = can.DefineMap.extend({});
var me = new Person();
me.age = 33 //-> throws "TypeError: Can't add property age, object is not extensible"If false, the object will not be sealed. This is the default behavior of
unextended DefineMaps. Use get and set to get and set values:
var person = new can.DefineMap();
person.set("first","Justin");
person.set("last","Meyer");
person.get("first") //-> "Justin"
person.get("last") //-> "Meyer"Set seal to false on objects that have an indeterminate number of properties:
var Style = can.DefineMap.extend({
seal: false
},{
cssText: {
get: function(){
return _.map(this.get(), function(val, prop){
return prop+": "+val;
}).join(";")
}
}
});
var style = new Style();
style.set("color","green");
style.set("font","awesome");
style.cssText //-> "color:green; font: awesome;"Creates a new instance of DefineMap or an extended DefineMap.
var person = new can.DefineMap({
first: "Justin",
last: "Meyer"
})- props
{Object}: Properties and values to seed the map with.
- returns
{can-define/map}: An instance ofcan.DefineMapwith the properties from props.
each iterates through the Map, calling a function
for each property value and key.
- callback
{function(item, propName)}: the function to call for each property The value and key of each property will be passed as the first and second arguments, respectively, to the callback. If the callback returns false, the loop will stop.
- returns
{can.Map}: this Map, for chaining
each iterates through the Map, calling a function
for each element.
- callback
{function(*, Number)}: the function to call for each element The value and index of each element will be passed as the first and second arguments, respectively, to the callback. If the callback returns false, the loop will stop.
- returns
{can.DefineList}: this DefineList, for chaining
- callback
{function(element, index, list)}: a function to call with each element of the DefineList The three parameters that callback gets passed are element, the element at index, index the current element of the list, and list the DefineList the elements are coming from. - thisArg
{Object}: the object to use asthisinside the callback
-
index
{Number}: where to start removing or inserting elements -
howMany
{Number}: the number of elements to remove If howMany is not provided,splicewill remove all elements fromindexto the end of the DefineList. -
newElements
{*}: elements to insert into the DefineList
- returns
{Array}: the elements removed bysplice
- collection
{Array|can.DefineList|can.Deferred}: the collection of new elements to use If a [can.Deferred] is passed, it must resolve to anArrayorcan.DefineList. The elements of the list are not actually removed until the Deferred resolves.
push adds elements onto the end of a DefineList.
- elements
{*}: the elements to add to the DefineList
- returns
{Number}: the new length of the DefineList
unshift adds elements onto the beginning of a DefineList.
- elements
{*}: the elements to add to the DefineList
- returns
{Number}: the new length of the DefineList
pop removes an element from the end of a DefineList.
- returns
{*}: the element just popped off the DefineList, orundefinedif the DefineList was empty
shift removes an element from the beginning of a DefineList.
- returns
{*}: the element just shifted off the DefineList, orundefinedif the DefineList is empty
indexOf finds the position of a given item in the DefineList.
- item
{*}: the item to find
- returns
{Number}: the position of the item in the DefineList, or -1 if the item is not found.
join turns a DefineList into a string by inserting separator between the string representations
of all the elements of the DefineList.
- separator
{String}: the string to seperate elements with
- returns
{String}: the joined string
reverse reverses the elements of the DefineList in place.
- returns
{can.DefineList}: the DefineList, for chaining
slice creates a copy of a portion of the DefineList.
-
start
{Number}: the index to start copying from -
end
{Number}: the first index not to include in the copy If end is not supplied,slicewill copy until the end of the list.
- returns
{can.DefineList}: a newcan.DefineListwith the extracted elements
- args
{Array|can.DefineList|*}: Any number of arrays, Lists, or values to add in For each parameter given, if it is an Array or a DefineList, each of its elements will be added to the end of the concatenated DefineList. Otherwise, the parameter itself will be added.