can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
91 lines (66 loc) • 2.85 kB
Markdown
@property {can.compute} can.Map.prototype.COMPUTE-ATTR
@parent can.Map.prototype 0
@deprecated {2.3} Using attributes as a compute directly have been deprecated in favor of the [can.Map.prototype.define define] plugin, which provides the same
functionality. It will still be maintained up to 3.0 and potentially after.
Projects using computes as a direct attribute should consider switching the
[can.Map.prototype.define define] plugin.
@description Specify an attribute that is computed from other attributes.
@option {can.compute} A compute that reads values on instances of the
map and returns a derived value. The compute may also be a getter-setter
compute and able to be passed a value.
@body
## Use
When extending [can.Map], if a prototype property is a [can.compute]
it will setup that compute to behave like a normal attribute. This means
that it can be read and written to with [can.Map::attr attr] and bound to
with [can.Map::bind bind].
The following example makes a `fullName` attribute on `Person` maps:
var Person = can.Map.extend({
fullName: can.compute(function(){
return this.attr("first") + " " + this.attr("last")
})
})
var me = new Person({first: "Justin", last: "Meyer"})
me.attr("fullName") //-> "Justin Meyer"
me.bind("fullName", function(ev, newValue, oldValue){
newValue //-> Brian Moschel
oldValue //-> Justin Meyer
})
me.attr({first: "Brian", last: "Moschel"})
## Getter / Setter computes
A compute's setter will be called if [can.Map::attr attr] is
used to set the compute-property's value.
The following makes `fullName` able to set `first` and `last`:
var Person = can.Map.extend({
fullName: can.compute(function(newValue){
if( arguments.length ) {
var parts = newValue.split(" ");
this.attr({
first: parts[0],
last: parts[1]
});
} else {
return this.attr("first") + " " + this.attr("last");
}
})
})
var me = new Person({first: "Justin", last: "Meyer"})
me.attr("fullName", "Brian Moschel")
me.attr("first") //-> "Brian"
me.attr("last") //-> "Moschel"
## Alternatives
[can.mustache] and [can.ejs] will automatically convert any function
read in the template to a can.compute. So, simply having a fullName
function like:
var Person = can.Map.extend({
fullName: function(){
return this.attr("first") + " " + this.attr("last")
}
})
var me = new Person({first: "Justin", last: "Meyer"})
Will already be live-bound if read in a template like:
{{me.fullName}}
// or
<%= me.attr("fullName") %>
The [can.Map.setter setter] plugin can also provide similar functionality as
Getter/Setter computes.