You can declare properties on your custom element by adding them to
the properties
object on your prototype. Adding a property to the properties
object allows a user to configure the property from markup (see
attribute deserialization for details).
Any property that's part of your element's public API should be declared in the
properties
object.
In addition, the properties
object can be used to specify:
- Property type.
- Default value.
- Property change observer. Calls a method whenever the property value changes.
- Read-only status. Prevents accidental changes to the property value.
- Two-way data binding support. Fires an event whenever the property value changes.
- Computed property. Dynamically calculates a value based on other properties.
- Property reflection to attribute. Updates the corresponding attribute value when the property value changes.
Many of these features are tightly integrated into the data system, and are documented in the Data system section.
Polymer({
is: 'x-custom',
properties: {
user: String,
isHappy: Boolean,
count: {
type: Number,
readOnly: true,
notify: true
}
},
ready: function() {
this.textContent = 'Hello World, I am a Custom Element!';
}
});
The properties
object supports the following keys for each property:
Key | Details |
---|---|
type |
Type: constructor (one of Boolean , Date , Number , String , Array or Object )Attribute type, used for deserializing from an attribute. Unlike 0.5, the property's type is explicit, specified using the type's constructor. See attribute deserialization for more information. |
value |
Type: boolean , number , string or function .Default value for the property. If |
reflectToAttribute |
Type: boolean Set to |
readOnly |
Type: boolean If |
notify |
Type: boolean If |
computed |
Type: string The value is interpreted as a method name and argument list. The method is invoked to calculate the value whenever any of the argument values changes. Computed properties are always read-only. See Computed properties for more information. |
observer |
Type: string The value is interpreted as a method name to be invoked when the property value
changes. Note that unlike in 0.5, property change handlers must be registered
explicitly. The |
Property name to attribute name mapping
For data binding, deserializing properties from attributes, and reflecting properties back to attributes, Polymer maps attribute names to property names and the reverse.
When mapping attribute names to property names:
-
Attribute names are converted to lowercase property names. For example, the attribute
firstName
maps tofirstname
. -
Attribute names with dashes are converted to camelCase property names by capitalizing the character following each dash, then removing the dashes. For example, the attribute
first-name
maps tofirstName
.
The same mappings happen in reverse when converting property names to attribute
names (for example, if a property is defined using reflectToAttribute: true
.)
Compatibility note: In 0.5, Polymer attempted to map attribute names to corresponding properties.
For example, the attribute foobar
would map to the property fooBar
if it was
defined on the element. This does not happen in 1.0—attribute to property
mappings are set up on the element at registration time based on the rules
described above.
Attribute deserialization
If a property is configured in the properties
object, an attribute on the
instance matching the property name will be deserialized according to the type
specified and assigned to a property of the same name on the element instance.
If no other properties
options are specified for a property, the type
(specified using the type constructor, e.g. Object
, String
, etc.) can be set
directly as the value of the property in the properties
object; otherwise it
should be provided as the value to the type
key in the properties
configuration object.
The type system includes support for Boolean and Number values, Object and Array values expressed as JSON, or Date objects expressed as any Date-parsable string representation.
Boolean properties are set based on the presence of the attribute:
if the attribute exists at all, the property is set to true
, regardless
of the attribute value. If the attribute is absent, the property
gets its default value.
<script>
Polymer({
is: 'x-custom',
properties: {
user: String,
manager: {
type: Boolean,
notify: true
}
},
attached: function() {
// render
this.textContent = 'Hello World, my user is ' + (this.user || 'nobody') + '.\n' +
'This user is ' + (this.manager ? '' : 'not') + ' a manager.';
}
});
</script>
<x-custom user="Scott" manager></x-custom>
<!--
<x-custom>'s text content becomes:
Hello World, my user is Scott.
This user is a manager.
-->
In order to configure camel-case properties of elements using attributes, dash- case should be used in the attribute name.
<script>
Polymer({
is: 'x-custom',
properties: {
userName: String
}
});
</script>
<x-custom user-name="Scott"></x-custom>
<!-- Sets <x-custom>.userName = 'Scott'; -->
Note: Deserialization occurs both at create time, and at runtime (for
example, when the attribute is changed using setAttribute
). However, it is
encouraged that attributes only be used for configuring properties in static
markup, and instead that properties are set directly for changes at runtime.
Configuring boolean properties
For a Boolean property to be configurable from markup, it must default to false
. If it defaults to true
, you cannot set it to false
from markup, since the presence of the attribute, with or without a value, equates to true
. This is the standard behavior for attributes in the web platform.
If this behavior doesn't fit your use case, you can use a string-valued or number-valued attribute instead.
Configuring object and array properties
For object and array properties you can pass an object or array in JSON format:
<my-element book='{ "title": "Persuasion", "author": "Austen" }'></my-element>
Note that JSON requires double quotes, as shown above.
Configuring default property values
Default values for properties may be specified in the properties
object using
the value
field. The value may either be a primitive value, or a function
that returns a value.
If you provide a function, Polymer calls the function once per element instance.
When initializing a property to an object or array value, use a function to ensure that each element gets its own copy of the value, rather than having an object or array shared across all instances of the element.
Polymer({
is: 'x-custom',
properties: {
mode: {
type: String,
value: 'auto'
},
data: {
type: Object,
notify: true,
value: function() { return {}; }
}
}
});
Property change notification events (notify)
When a property is set to notify: true
, an event is fired whenever the
property value changes. The event name is:
property-name-changed
Where property-name
is the dash-case version of
the property name. For example, a change to this.firstName
fires
first-name-changed
.
These events are used by the two-way data binding system. External
scripts can also listen for events (such as first-name-changed
)
directly using addEventListener
.
For more on property change notifications and the data system, see Data flow.
Read-only properties
When a property only "produces" data and never consumes data, this can be made
explicit to avoid accidental changes from the host by setting the readOnly
flag to true
in the properties
property definition. In order for the
element to actually change the value of the property, it must use a private
generated setter of the convention _setProperty(value)
.
<script>
Polymer({
properties: {
response: {
type: Object,
readOnly: true,
notify: true
}
},
responseHandler: function(response) {
this._setResponse(response);
}
});
</script>
For more on read-only properties and data binding, see How data flow is controlled.
Reflecting properties to attributes
In specific cases, it may be useful to keep an HTML attribute value in sync with
a property value. This may be achieved by setting reflectToAttribute: true
on
a property in the properties
configuration object. This will cause any
observable change to the property to be serialized out to an
attribute of the same name.
<script>
Polymer({
properties: {
response: {
type: Object,
reflectToAttribute: true
}
},
responseHandler: function(response) {
this.response = 'loaded';
// results in this.setAttribute('response', 'loaded');
}
});
</script>
Attribute serialization
When reflecting a property to an attribute or binding a property to an attribute, the property value is serialized to the attribute.
By default, values are serialized according to value's current type
(regardless of the property's type
value):
String
. No serialization required.Date
orNumber
. Serialized usingtoString
.Boolean
. Results in a non-valued attribute to be either set (true
) or removed (false
).Array
orObject
. Serialized usingJSON.stringify
.
To supply custom serialization for a custom element, override your element's serialize
method.
Moved sections
The following section have moved to Observers and computed properties:
The following sections have moved to Work with object and array data: