Observers
Sometimes, it is needed to listen to changes in some properties and react on them. For example, we may want to send some notifications to a server when users enter some information.
The example below demonstrates it. Basically, users can choose a type of their company and we save this information somewhere in a database.
Company type selector
Source code
<html>
<head>
<link rel="import" href="src/polymer-advanced/observers/company-type-select.html">
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
</head>
<body>
<company-type-select></company-type-select>
</body>
</html>
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../../bower_components/polymer/lib/elements/dom-if.html">
<!-- Material design implementation of a radio button -->
<link rel="import" href="../../../bower_components/paper-radio-button/paper-radio-button.html">
<!-- PaperRadioGroup allows you to group radio buttons, so only one can be selected at any time -->
<link rel="import" href="../../../bower_components/paper-radio-group/paper-radio-group.html">
<!-- Decorative spinner that indicates that something is happening in the background -->
<link rel="import" href="../../../bower_components/paper-spinner/paper-spinner.html">
<dom-module id="company-type-select">
<template>
Please select a type of your company:
<paper-radio-group selected="{{companyType}}">
<!-- We are disabling radio buttons when we send a notification to a server just to simplify an application -->
<!-- and prevent a user from rapidly changing settings -->
<paper-radio-button name="ltd" disabled="[[persistenceInProgress]]">LTD</paper-radio-button>
<paper-radio-button name="llp" disabled="[[persistenceInProgress]]">LLP</paper-radio-button>
</paper-radio-group>
<br/>
<template is="dom-if" if="[[persistenceInProgress]]">
<paper-spinner active></paper-spinner>
</template>
</template>
<script>
class CompanyTypeSelect extends Polymer.Element {
static get is() {
return 'company-type-select';
}
static get properties() {
return {
companyType: {
type: String,
observer: 'companyTypeChanged'
},
persistenceInProgress: {
type: Boolean,
value: false
}
}
}
// The function accepts 2 parameters. In our case we don't need them
// so we could just write 'companyTypeChanged: function()'.
// Based on radio-buttons we can say that newValue would be either 'ltd' or 'llp'.
companyTypeChanged(newValue, oldValue) {
this.set('persistenceInProgress', true);
// It's a stub instead of sending some asynchronous request
setTimeout(function() {
this.set('persistenceInProgress', false);
}.bind(this), 1000);
}
}
customElements.define(CompanyTypeSelect.is, CompanyTypeSelect);
</script>
</dom-module>
Observers can be much more complex. For example, you may want to monitor changes in several different properties.
Let’s enhance our previous example by adding a contact name input.
<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">
<link rel="import" href="../../../bower_components/paper-radio-button/paper-radio-button.html">
<link rel="import" href="../../../bower_components/paper-radio-group/paper-radio-group.html">
<link rel="import" href="../../../bower_components/paper-spinner/paper-spinner.html">
<dom-module id="company-type-select-enhanced">
<template>
<div>
Please select a type of your company:
<paper-radio-group selected="{{companyType}}">
<paper-radio-button name="ltd" disabled="[[persistenceInProgress]]">LTD</paper-radio-button>
<paper-radio-button name="llp" disabled="[[persistenceInProgress]]">LLP</paper-radio-button>
</paper-radio-group>
</div>
<div>
<paper-checkbox disabled="[[persistenceInProgress]]" checked="{{notificationSubscription}}">
I want to get notifications
</paper-checkbox>
</div>
<br/>
<div>
<template is="dom-if" if="[[persistenceInProgress]]">
<paper-spinner active></paper-spinner>
</template>
</div>
</template>
<script>
class CompanyTypeSelectEnhanced extends Polymer.Element {
static get is() {
return 'company-type-select-enhanced';
}
static get properties() {
return {
companyType: String,
name: String,
notificationSubscription: Boolean,
persistenceInProgress: {
type: Boolean,
value: false
}
}
}
// This static getter is used to specify an array of observers
static get observers() {
return [
'userInfoChanged(companyType, notificationSubscription)'
];
}
userInfoChanged(companyType, notificationSubscription) {
this.set('persistenceInProgress', true);
setTimeout(function() {
this.set('persistenceInProgress', false);
}.bind(this), 1000);
}
}
customElements.define(CompanyTypeSelectEnhanced.is, CompanyTypeSelectEnhanced);
</script>
</dom-module>
Enhanced company type selector
- What we have learned so far
-
-
We can monitor changes in a single property by using an
observer
attribute. An observer function accepts 2 arguments: an old value and a new one. -
We can monitor several properties at the same time by using observers array. But we lose information about old values in this case.
-