Computed Properties
Sometimes you may need properties that depend on other properties. For example, you have properties firstName
, lastName
and also need property fullName
that concatenates first and last names. Or you have a boolean property that defines if a button is enabled or disabled, and this property depends on a number of other properties.
Obviously, you shouldn’t manually change a value for such synthetic properties, it should be calculated automatically. Luckily, Polymer provides so called computed properties, and below is an example of using them.
Source code
<html>
<head>
<link rel="import" href="src/polymer-advanced/computed-properties/service-agreement.html">
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
</head>
<body>
<service-agreement></service-agreement>
</body>
</html>
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../../bower_components/polymer/lib/elements/dom-if.html">
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../bower_components/paper-checkbox/paper-checkbox.html">
<dom-module id="service-agreement">
<template>
<template is="dom-if" if="[[!applicationConfirmed]]">
<div>
<label>
Please enter your name and accept our agreement before continuing.
</label>
</div>
<br/>
<div>
<iron-input bind-value="{{name}}">
<input />
</iron-input>
</div>
<br/>
<div>
<paper-checkbox checked="{{agreementConfirmed}}">I have read and accepted this agreement</paper-checkbox>
</div>
<br/>
<div>
<!-- continueEnabled is a computed property -->
<!-- but it's used as any other property would be used -->
<button disabled="[[!continueEnabled]]" on-click="continuePurchase">Continue</button>
</div>
</template>
<!-- After a user enters all details and confirms a form we show him this confirmation message -->
<template is="dom-if" if="[[applicationConfirmed]]">
<h3>Thank you for your collaboration! We will analyze your application and contact you in 24 hours.</h3>
</template>
</template>
<script>
class ServiceAgreement extends Polymer.Element {
static get is() {
return 'service-agreement';
}
static get properties() {
return {
name: {
type: String,
value: ''
},
agreementConfirmed: {
type: Boolean,
value: false
},
// It's a computed property
continueEnabled: {
type: Boolean,
// In 'computed' property we provide a name of a method to calculate a value
// and pass in it all properties this property depends on.
// The property is re-calculated each time the properties it depends on change.
computed: 'isContinueEnabled(name, agreementConfirmed)'
},
applicationConfirmed: {
type: Boolean,
value: false
}
}
}
isContinueEnabled(name, agreementConfirmed) {
return name.length > 0 && agreementConfirmed;
}
continuePurchase() {
this.set('applicationConfirmed', true);
}
}
customElements.define(ServiceAgreement.is, ServiceAgreement);
</script>
</dom-module>
Result
In this example, users cannot submit a form until they type in their name and accept an agreement.
It’s essential to specify what properties we depend on. You cannot just type computed: "isContinueEnabled()"
and then use this.name
and this.agreementConfirmed
in the isContinueEnabled
method, because then Polymer won’t know what properties we depend on and it won’t re-calculate a computed property when required.
- What we have learned so far
-
-
We can use computed properties when we need some information that can be calculated based on other properties.
-