I'm using the polymer application drawer template from the polymer cli.
I'm having some trouble with:
- When you load a new page, the html element is imported; then it's code executes
- When I move to another page the code for the previous page is still running.
Is there a way to destroy and create the page/element or suspend and enable?
Whats the best practice for dealing with this problem?
Have the pages implement a create and destroy method and invoke it when changing page?
Ie
oldPageElement.destroy();
newPageElement.create();
Polymer({
is: 'my-random-page',
behaviors: [MyBehaviors.CommonPageBehavior],
/**
* @override
*/
create: function() {..}
/**
* @override
*/
destroy: function() {..}
})
You actually don't need to implement anything complicated, but just use a mere dom-if
.
Working prototype: http://jsbin.com/gezihatera/edit?html,console,output
As you can see, the "View One" uses a custom page element, which is always restamped when re-selected. Other pages are ordinary div
elements, since this is only a minimal prototype. But this also shows that you can selectively choose which pages get restamped and which do not (if you don't always need this).
The essence is the following: as per dom-if documentation, if you set the restamp
attribute to true
, then the dom-if
will always create and destroy your pages upon selecting/deselecting them. You can see this in the console, where I print out sample-page ready
on every ready
element. I also create a helper function _equals
to help with comparing whether the specified page is really selected.
To sum up, let me paste the code for the app:
<dom-module id="sample-app">
<template>
<style>
:host {
display: block;
}
</style>
<iron-selector selected="{{page}}" attr-for-selected="name">
<a name="view1" href="#">View One</a>
<a name="view2" href="#">View Two</a>
<a name="view3" href="#">View Three</a>
</iron-selector>
<iron-pages role="main" selected="[[page]]" attr-for-selected="name">
<template is="dom-if" if="[[_equals(page, 'view1')]]" restamp="true">
<sample-page name="view1">view1</sample-page>
</template>
<div name="view2">view2</div>
<div name="view3">view3</div>
</iron-pages>
</template>
<script>
Polymer({
is: 'sample-app',
_equals: function(a, b) {
return a == b;
},
});
</script>
</dom-module>
And the code for the sample page:
<dom-module id="sample-page">
<template>
<style>
:host {
display: block;
}
</style>
<content></content>
</template>
<script>
Polymer({
is: 'sample-page',
ready: function() {
console.log('sample-page ready');
},
});
</script>
</dom-module>
Hope this satisfies your question.
Note: you should not put the name
attribute on the dom-if
itself, but rather onto its content (the same way I did).
Thought I would post my solution after implementing @alesc's dom-if to get the element to be deactivated.
// after a successful importHref, _pageLoaded is called.
_pageLoaded: function(pageName) {
var name = 'my-' + pageName;
this.async(function() {
// async to wait for element restamping, if done
var pages = this.$.pages;
var page = pages.querySelector(name);
page.load()
.then(page.isAuthorized.bind(this))
.catch(this._catchPageIsAuthorizedError.bind(this))
.then(this._shouldSetPage.bind(this, pageName));
}.bind(this));
}