Dom-repeat and neon-animatable in Polymer - polymer

I have a same problem with use dom-repeat for neon-animatable in Polymer.
So, about my problem. When I dynamic building page, I use dom-repeat for building a certain number of pages. In code that look like
<neon-animated-pages id="views"
class="flex"
selected="[[selected]]"
entry-animation="[[entryAnimation]]"
exit-animation="[[exitAnimation]]">
<template is="dom-repeat" items="{{dataView}}">
<neon-animatable id="{{item.id}}">
<inner-content data="{{item.content}}"></inner-content>
</neon-animatable>
</template>
</neon-animated-pages>
After builded this page, I have a page which contains a certain numbe neon-animatable pages, but after first click on button for view next page , animation don't work, but if click on button more, animation work fine.
So, I can't understand why first animate don't work
If who have some mind about how resolve this problem, I will be grateful
P.S About my observations
When use in static code like this
<neon-animated-pages>
<neon-animatable>page 1</neon-animatable>
<neon-animatable>page 2</neon-animatable>
<neon-animatable>page 3</neon-animatable>
</neon-animated-pages>
Animation it is running the first time

This appears fixed for a future release: https://github.com/PolymerElements/neon-animation/issues/55
Details:
I ran into the same problem and it appears related to timing on when the light DOM children are created.
Short answer: on your custom element add an attached function that sets the selected page.
attached: function () {
this.async(function () {
this.$.pages.select(0);
});
}
Long Answer
When a template dom-repeat is used inside the neon-animated-pages, at the point the web component is initialized it is not able see the details of the light DOM children.
Using static code the tree is seen as:
neon-animated-pages
- neon-animatable
- neon-animatable
- neon-animatable
Using dom-repeat at initialization it looks like:
neon-animated-pages
- template
Because of this when the neon-animated-pages tries to set the selected page it get undefined because it is not able to see the neon-animatable components. These get created later. This behavior is described in the documentation https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html which says
Note that initialization order of may vary depending on whether or not the browser includes native support for web components. In particular, there are no guarantees with regard to initialization timing between sibling elements or between parents and light DOM children. You should not rely on observed timing to be identical across browsers, except as noted below ... This means that an element’s light DOM children may be initialized before or after the parent element, and an element’s siblings may become ready in any order.
As the light DOM children starts getting filled in a call is made to the observer function "_updateSelected" on IronSelectableBehavior, which is the parent of NeonAnimatedPages, to update the selections based on the content updates.
However, NeonAnimatedPages also maintain internal references to identify selected items and uses the observer function "_selectedChanged" to setup references and control animations. Essentially it decides to display an animation based on whether a previous element is selected. Based on the tree above, when this method is called at initialization it cannot see the full tree and it sets previously selected to undefined. As the light DOM is getting populated, this handler is not getting called because the selected value is not changing only the content is changing. The consequence is that while IronSelectableBehavior correctly knows what is selected, NeonAnimatedPages still thinks nothing is selected, and as you make your initial screen change it treats it as an initial load because it thinks nothing is selected and suppresses the animation.
The solution essentially waits for the entire tree to be built and then sets the selected value so that all the event handlers are able to correctly see the light DOM children and set up internal references.

As Ade mentioned, this was a logged issue in neon-animation, but it has since been fixed. Update the component (bower update, if you're using bower) to resolve the issue. I would have added this as a comment to Ade's answer, but I don't have enough reputation yet

Related

Why are we NOT supposed to mix DOM code with Angular code?

I am designing a master and child grid in which by clicking on a row of the master grid, data in the child grid changes accordingly. To do so, after clicking on a row of the master grid, I call reloadItmes() from the child controller like below:
$("#masterTable tbody").on("click", "tr", function (event) {
event.preventDefault();
jQuery(this).addClass('selected').siblings().removeClass('selected');
angular.element($('#childTable')).scope().reloadItems();
});
However, I found out that mixing DOM code with Angular code is not a good practice, but I don't know what problem this piece of code could cause.
because of the conflicts between angular scope and dom.
actually they are in different time cycles and it is not a good idea to mix them both with each other.
I had this problem and at last I had to call a fake function in angular to force it to read my dom changes and apply them. It is totally a synchronization problem.
so if you could put both code portions into one controller or either do it all in pure js the result would have better performance and it is much easier to expand or understand.

Issue with selection in Screenshot manager

We have built custom state saving functionality into our web app, based largely on the "Screenshot Manager" extension that Philippe created. We are having an issue with selection, wherein some components that where hidden when the state was saved are being shown when the state is loaded. I have replicated it on viewer.autodesk.io with the vanilla states manager code.
To be precise, components already visible in the viewer that are hidden by CTRL-clicking them on the model browser initially disappear in the viewer. However, when you save this state and then recall the state at a later time, the components hidden in this way re-appear.
Can you please investigate - is this a bug in the states manager code (we had a look but can't find it - the hidden components are being recorded in the state) or in the viewer itself?
Thanks,
Chris
I check what happen when you select components, those 2 states are incompatible: the child gets hidden but the parent gets isolated, hence it is displaying all its children and hide the rest of the components in the model.
In order to get the behavior you "would" expect, you would need to hide all components without isolating the parent sub-assemlbly, then create your first state, then hide the child, create your second state. You may achieve that by writing your handler when clicking a browser node. For that you would need to implement your own ModelStructurePanel.
I've got a basic example which can help you getting started:
ModelStructurePanel
I will take a look at the click handler and add an example there. For the time being, you can check in the source of the viewer3D.js which methods you need to overwrite.
Hope that helps

How to debug Polymer dom-repeat

I am developing a Polymer component that uses <template is="dom-repeat" items="rows"> to populate a table, and need to debug what is happening in some rows. In Chrome developer tools I can select the component in the DOM and inspect all of the rows array using $0.rows. But how do I inspect the data for an individual row? If I select one of the generated row elements, is there any connection between $0 and the array item used to generate the row?
As per the docs, you can use the modelForElement(el), itemForElement(el) and keyForElement(el) functions.
this.$.repeater.modelForElement($0)
It can be used on any node, not only the top level element of the repeated template. Getting the this.$.repeater can be tricky from the Dev tools though. The above would assume a breakpoint inside your element.
As a second option you can take advantage of the fact that each top level element stamped by the repeater gets an additional property called _templateInstance. It will contain all the data you need. Remember however that this is internal implementation detail and could change as Polymer evolves. So debug but don't use that in your code.

Properly instantiating a template instance so that everything is present (model data, filters, event handlers)

I'm a bit of trouble instantiating a custom template, and making all the bindings work. My custom element which has to do this is quite similar to polymer/core-list, with a few differences. Like core-list, the parent adds the element invokes my custom element, and adds a template as its content, as seen here.
Unlike core-list, the element adds an id to this template, and creates a few templates which refer to that one, as seen here. Finally, when the time comes, these new templates are used to create a few elements and add them in the dom.
That's all fine and good, and mostly, it works correctly. The model data is used to fill the resulting element correctly, and the default filters work, thanks to the PolymerExpressions used as a bindingDelegate. However, event handlers do not seem to work.
I don't know whether the handler function can't be found in whatever scope is used, or something else is at play here. The only thing I currently know is that the on-tap attribute value is empty when I look at the polymer-icon-button through the web inspector. With a very similar usage using the core-list, the event handler works. The web inspector there shows the polymer expression as the value of the on-tap attribute. And both handlers are defined in the parent element which contains the invokations of core-list and my element, and the templates which are passed to the corresponding contents.

Using a single shared element across multiple partial views

I have a basic ASP.Net MVC 3 application which has a number of controllers and a number of actions (and subsequently views)
A common feature of the application is to show a pop-up dialog window for basic user input. One of the key features of this dialog process is a faded mask that gets shown behind the dialog box.
Each of these dialog window controls is in a separate Partial View page.
Now, some view pages may use multiple dialog boxes, and therefore include multiple partial views in them - which as is would mean multiple instances of the "mask" element.
What I am trying to find a solution for is to only need to create one instance of a "mask" element regardless of the number of dialog partial views I include, and then the script in each partial dialog will have access to this element (so basically it just needs to be on the page somewhere)
The only real idea I have come up with so far is to add the "mask" element to the master page (or in the original view page) and this will mean it only gets added once. The problem here is that it will be added even when it is not needed (albeit one small single element)
I can live with this, but I would like to know if there is a better way to handle these kinds of scenarios?
A quick idea that came to mind is some kind of master page inheritance hierarchy, So I may have a DialogMasterPage that inherits from the standard current master page. How does that sound for an approach?
Thanks
To do something like this, where each module can register their need for a certain thing in the master page, you can use HttpContext to store a flag of whether you need to write the mask div, and just set that property in each partial. At the end of the master page, if the flag is set, you can then write the mask div if its set to true.
Obviously to make this cleaner you could wrap it all in an HtmlHelper extension or something.
My initial thought is for you to use something like jQuery UI where it handles the masking for you or if you are using something custom you can load the content for the dialog via ajax then show it in the single dialog on the master page.