set
can.Map.prototype.define.set
Specify what happens when a value is set on a map attribute.
set( [newVal,] [setValue] )
A set function defines the behavior of what happens when a value is set on a can.Map. It is typically used to:
- Add or remove other attributes as side effects
- Coerce the set value into an appropriate action
The behavior of the setter depends on the number of arguments specified. This means that a setter like:
define: {
prop: {
set: function(){}
}
}
behaves differently than:
define: {
prop: {
set: function(newVal){}
}
}
Parameters
-
newVal
{*}
OptionalThe type function coerced value the user intends to set on the can.Map.
-
setValue
{function(newValue)}
OptionalA callback that can set the value of the property asyncronously.
Returns
{* | undefined}
If a non-undefined value is returned, that value is set as the attribute value.
If an undefined
value is returned, the behavior depends on the number of
arguments the setter declares:
- If the setter does not specify the
newValue
argument, the attribute value is set to whatever was passed to attr. - If the setter specifies the
newValue
argument only, the attribute value will be removed. - If the setter specifies both
newValue
andsetValue
, the value of the property will not be updated untilsetValue
is called.
Use
An attribute's
set
function can be used to customize the behavior of when an attribute value is set via attr. Lets see some common cases:Side effects
The following makes setting a
page
property update theoffset
:The following makes changing
makeId
remove themodelId
property:Asynchronous Setter
The following shows an async setter:
Behavior depends on the number of arguments.
When a setter returns
undefined
, its behavior changes depending on the number of arguments.With 0 arguments, the original set value is set on the attribute.
With 1 argument,
undefined
will remove the property.With 2 arguments,
undefined
leaves the property in place. It is expected thatsetValue
will be called:Side effects
A set function provides a useful hook for performing side effect logic as a certain property is being changed.
For example, in the example below, Paginator can.Map includes a
page
property, which derives its value entirely from other properties (limit and offset). If something tries to set thepage
directly, the set method will set the value ofoffset
:Merging
By default, if a value returned from a setter is an object, array, can.Map, or can.List, the effect will be to replace the property with the new object completely.
By contrast, if you access a property of a Map using
.attr
, then change it by calling.attr
on it directly, the new properties will be merged with the existing nested Map, not replaced.If you would rather have the new Map or List merged into the current value, not replaced, call
attr
inside the setter:Batched Changes
By default, calls to set methods are wrapped in a call to can.batch.start and can.batch.stop, so if a set method has side effects that set more than one property, all these sets are wrapped in a single batch for better performance.