I run on loop on the list (this is array). and for every I create icon-status with property item.status.
I want that is item.status changed for some reason also the property to the icon will change.
<template is="dom-repeat" items="{{list}}">
<paper-item>
<paper-item-body>
<div class="horizontal layout font-md">
//this is also dont bind on change
<icon-status state={{item.status}} size=7></icon-status>
<div class="flex"></div>
//this is not bind on change
<div class="gray">{{item.status}}</div>
</div>
</paper-item-body>
</paper-item>
</div>
</div>
</template>
I tried using timeout change the status of the items and the view does not update.
How can I bind this?
Thanks
To add binding support for list:
To update the value in the current element, use this.set('list.0.status', 'newStatus');
To update the value in a parent element, add list as a property on the current element:
list: { type: Array, notify: true }
Consider changing your template binding from two-way to one-way as the data is only flowing in one direction, <template is="dom-repeat" items="[[list]]">
Related
I have the following piece of code:
<dom-repeat id="template" items="{{chats}}">
<template>
<template is="dom-if" if="[[item.opened]]">
<section id$="msg-[[index]]"></section>
</template>
</template>
</dom-repeat>
How do can I access section with id=msg-3 and set scrollTop to 999 upon being rendered?
I know that in polymer 1 the best practice was to bind to on attached and wait on a dom-repeat event with a debouncer this no longer works in polymer 3, however.
If you know the index number you can access the element with ;
let el = this.shadowRoot.querySelector('#msg-'+<index>);
Remember, if item not rendered due to your filter with dom-if, you can not acces this element.
EDIT
In order to show on top of the selected item;
let screenPosition = el.getBoundingClientRect();
window.scrollTo(screenPosition);
Demo
I read carefully these threads
Polymer 1 nested dom-if within dom-repeat not updating when data changes
how to dynamically append an element to dom-if in Polymer?
How to access content of dom-if inside a custom element?
that may have some relation with my question but I didn't manage find any clue if I can do what I want and how.
In my company, there are several flows, each one for each business flow and each step of the flow is a screen coded as a Polymer 1 web component. All them are warraped in a root Polymer component which defines the route.
A simple exemple would be:
my-root-component:
<dom-module id="my-root-component">
<template>
<first-obrigatiory-page which-route={aValueReturnedFromFirstComponent}></first-obrigatiory-page>
<template is="dom-if" if="[[_isTrueFunction(aValueReturnedFromFirstComponent)]]" restamp>
<second-page which-sub-route={aValueReturnedFromSecondComponent}></second-page>
<template is="dom-if" if="[[_isTrueFunction(aValueReturnedFromSecondComponentComponent)]]" restamp>
<third-page ></third-page>
</template>
</template>
</template>
<script>
Polymer({
is: 'my-root-component',
behaviors: [doesntMatterHere],
properties: {
The first dom-if works as expected but the second seems not be taken in account and my third-page component is never showed.
I checked and the equivalent for _isTrueFunction(aValueReturnedFromSecondComponentComponent) is returning true.
Does aValueReturnedFromFirstComponent really return anything, because you should declare the attribute as which-route="{{aValueReturnedFromFirstComponent}}" instead of using simple { }.
Does the whichRoute (note the camelCase) property in the first-obrigatiory-page element have the notify: true property so the variable actually sends back the updated value?
I usually set observers on variables whenever dom-ifs don't update so I can see if they really change or not, and then set the variables myself through the console with document.querySelector('my-root-component').set('aValueReturnedFromFirstComponent', true) so I can see that the dom-if really updates.
A workaround could be to use events, but what you've done should work.
In polymer, let's say I have a container element <x-container>, and two child elements <a-child>, <b-child>. In an element, I want to be able to specify that it contains either <a-child> or <b-child> (it will never have both).
For example, it could look like:
1. <x-container><a-child></a-child></x-container>
or,
2. <x-container><b-child></b-child></x-container>.
Since <x-container> has a lot of code, I don't want to duplicate it, but want to be able to use an <x-container> like this:
<x-container type = 'a-child'></x-container> which would then have the same behavior as the first item mentioned. How could I achieve this functionality?
Just instanciate it when you have the information which one its going to be!
//in your x-container component
observers: ['_typeChanged(type)'],
_typeChanged: function(type) {
var child = this.create(type);
Polymer.dom(this.root).appendChild(child);
}
Or you use a slot then you could do smth like this
parent component
<x-container>
<template is="dom-if" if="[[_isA()]]"><a-child></a-child></template>
<template is="dom-if" if="[[_isB()]]"><b-child></b-child></template>
</x-container>
and in your x-containerĀ“s template just simply put a slot the child will be rendered within the slot
<slot></slot>
I have the following nested dom-repeat:
<firebase-query
id="query"
path="[[path]]"
data="{{parentItems}}"
app-name="myApp">
</firebase-query>
<template is="dom-repeat"
items="{{parentItems}}"
as="parentItem">
<template is="dom-repeat" items="{{_toArray(parentItem)}}">
<div>{{item.details}} </div>
</template>
</template>
When items are added/removed from parentItems, the nested child dom-repeat template is not re-rendering i.e. _toArray() is not called. Is this behaviour expected? How do I ensure that when parentItems changes, the nested template will also be updated? Thanks.
I don't have the details of how you add something in the parentItems property, but i assume you do something like this
this.parentItems.push(something)
Polymer won't see the array change in that case, try to use the polymer push instead,
this.push('parentItems', something)
It will push it in the array, and notify polymer binding to update the view.
Is it possible to get the elements that will be/were rendered from a <template repeat>?
I have a component called poly-list, implemented below:
<poly-list dataList="{{ data.in }}" id="inList"
style="overflow: hidden; min-width: 324px; display: inline-block;">
<template>
<div> <!-- on-click event here -->
<paper-input-no-error value="{{ [0] }}"
class="in-paper-input"
on-change="{{ inChanged }}" id="0"></paper-input-no-error>
<paper-input-no-error value="{{ [1] }}"
class="in-paper-input"
placeholder="Value" id="1"></paper-input-no-error>
</div>
</template>
</poly-list>
I then activate the template in the domReady callback:
this.template.model = this.data;
this.template.setAttribute('repeat', '');
I need a way to get each individual element that the template will put into the DOM. I need to do this in order to add an event listener to each component that is rendered. I also want this to be encapsulated in my poly-list components so components implementing poly-list will not need to setup the event itself.
I need to add the event to the top level element in the template repeat. In this case it is the div. I commented where I mean in the code above. Event bubbling could work but would not be reusable due to the fact that I do not know how for in the element will be that triggered the event thus making it impossible to say the top level element is always 1 parent element above as in the example above.
Is there an event that will return each element as it is rendered or something similar?
"Is it possible to get the elements that will be/were rendered from a template repeat?"
Yes, but only after Template Repeat has finished. Then you can select the elements by automatic node finding: this.$
There is an example here: How can I know that Template Repeat has finished?
Can't you just use Polymer's declarative event binding?
<poly-list ...>
<template>
<div on-click="{{ clickHandler }}">
<paper-input-no-error ...></paper-input-no-error>
<paper-input-no-error ...></paper-input-no-error>
</div>
</template>
</poly-list>
(with a method on your outer element's prototype called clickHandler)
With regards to bubbling, there probably is some way which you could get it to work.