Polymer JS conflicts with Rails Turbolinks

瘦欲@ 提交于 2020-01-02 06:09:46

问题


Trying to use PolymerJs with a Ruby on Rails project with Turbolinks enabled. The initial loading of Polymer components works,but when I click on a link the new page renders, but my Polymer components are not reinitialized. Instead they look as if no JS has been run on them at all.

I am loading polymer components and platform in the header, so they are not loaded with the 'page changes' (this is how turbolinks works - it only reloads the body).

I seem to be able to 'fake it' by doing the following assuming I wanted to 'refresh' my-custom-element and the core-ajax tags on my page

custom_elements = document.querySelectorAll("my-custom-element, core-ajax ") 
for element in custom_elements 
  element.parentNode.replaceChild(element.cloneNode(), element) 

I am guessing there is a more idiomatic way to do it though. Also tried to call the Polymer() call inside the element again with out success. It seems like it fires properly, but there is no attachment of the shadowDom or any other activity indicating Polymer has attempted to reattach my elements. I also tried using preventDispose, but that does not seem to work as an entirely new body is being loaded from the server.

How can I tell Polymer/Platform to reinitialize all elements on my page? What events should I be calling?

Or if that cant be done, how do a initialize just a given polymer element.


回答1:


Written for Turbolinks 4. Untested in Turbolinks 5

Turbolinks replaces the Document Body after fetching it via replaceChild

https://github.com/rails/turbolinks/blob/master/lib/assets/javascripts/turbolinks.js.coffee#L97

document.documentElement.replaceChild(body, document.body);

This is not trigger the 'upgrading of elements' as it seems the Observers do not fire in this case.

I have come up with 2 different solutions to get around this.

Importing the entire body

$(document).on "page:change", ->
   document.documentElement.replaceChild(document.importNode(document.body, true), document.body);

Importing just the specific registered Polymer Elements

$(document).on "page:change", ->
  for polymerElement in Polymer.elements
    for domElement in document.body.querySelectorAll(polymerElement.name)
      domElement.parentNode.replaceChild(document.importNode(domElement, true), domElement);

Update

This seems to align with the officially endorsed way to handle this situation

https://groups.google.com/forum/#!msg/polymer-dev/WaWbepYW97Q/XE3SQTyvyCUJ

Also a good use case for why this step is required

To see why you might want to avoid changing type when adopting, consider an element born in an that gets moved into the main document. You probably wouldn't want to go back through the lifecycle just because it moved to a new document...



来源:https://stackoverflow.com/questions/25749658/polymer-js-conflicts-with-rails-turbolinks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!