ergo / polymer-ui-router

UI-router wrapper for Web Components
Apache License 2.0
22 stars 6 forks source link

[bug] Components of abstract states' children are not rendered #12

Closed mknxdev closed 6 years ago

mknxdev commented 6 years ago

Hi, Here I come today because I really liked the UI-Router but I have a Polymer project that needs to manage app routing. So I was glad to find out your UI-Router wrapper for Polymer! :)

But here I am: with AngularJS, I was used to use abstract states that do not have any HTML or template associated to them, but I was often using them to define "parent" states for nested states. For example (in AngularJS syntax):

$stateProvider
    .state('contacts', {
        abstract: true,
        url: '/contacts'
    })
    .state('contacts.list', {
        url: '/list',
        views: { 'app-content@': { template: '<div contacts-list></div>' } }
    })
    .state('contacts.edit', {
        url: '/edit',
        views: { 'app-content@': { template: '<div contacts-edit></div>' } }
    })
    .state('contacts.new', {
        url: '/new',
        views: { 'app-content@': { template: '<div contacts-new></div>' } }
    });

These abstract states were very useful if you wanted to have a common prefix in a URI without defining any HTML or template associated to them (these are children states that handle HTML rendering).

But I think there is a little bug in your wrapper, and it seems to not take care of the abstract key in the state definition (in PolymerUiRouter-compliant syntax). The fact is, for each state I define which is a child of an abstract state, the associated component is not rendered in the <uirouter-uiview>. So my route is working, as well as the URL update and my lazy-loading import, but the view component is just not rendered.

Could you take a look at this little bug in the next few days? It could be really useful!

Thanks, and keep up the good work!

PS: Don't hesitate if you need more information about this bug.

ergo commented 6 years ago

Hi, @mknxio - can you provide some simple test case, so we can quickly iterate and see what is wrong?

https://github.com/ergo/polymer-ui-router/blob/master/uirouter-router.html#L145 - I don't think I do anything special with state definitions so UI router should get all the config variables that you set.

I also used abstract in my 1.5 Angular app, but I'm not sure if this is still supported in latest version of the router.

ergo commented 6 years ago

Hm, actually I think it is https://ui-router.github.io/core/docs/latest/interfaces/state.statedeclaration.html as per docs. I'll add abstract route to one of the demo files and try to debug whats going on there, thanks for pointing this out.

mknxdev commented 6 years ago

Yes I saw that you're only injecting the source state definition in the UI-Router and that's why I don't understand why no rendering occurs in that case. I also took a look at the UI-view component but all seems to be good.

Thanks for the quick reply. I'll try to add here soon a sample where this bug is present.

ergo commented 6 years ago

Sure, @mknx-io I developed this component with direct help of Chris Thielen (he did most of the heavy lifting and UI router creator) so its possible I missed something in the wrapper. If we have a demo we can try to debug it ourselves or show to Chris and ask about some internals.

mknxdev commented 6 years ago

Ok so here is a simplified version of the project I'm working on, where I found the bug (all of this code is in the same file, the main app component).

HTML part

<dom-module id="my-app">
  <template>
    <style>
      /* ... */
    </style>

    <!--
      _routerLocationPlugin: pushStateLocationPlugin or hashLocationPlugin (from @uirouter/core)
      initCallback, before and afterRouterTransition are simple callback functions
    -->
    <uirouter-router
        id="uiRouter"
        location-plugin="[[ _routerLocationPlugin ]]"
        states="[[ states ]]"
        init-callback="[[ initCallback ]]"
        on-uirouter-exit="beforeRouterTransition"
        on-uirouter-success="afterRouterTransition">
    </uirouter-router>

    <!-- ... -->

    <!-- Nav. menus -->
    <app-drawer id="drawer" slot="drawer" swipe-open="[[narrow]]">
      <uirouter-sref-active>
        <uirouter-sref state="contacts.list">List contacts</uirouter-sref>
      </uirouter-sref-active>
      <uirouter-sref-active>
        <uirouter-sref state="contacts.new">Create contact</uirouter-sref>
      </uirouter-sref-active>
      <uirouter-sref-active>
        <uirouter-sref state="contacts.edit">Edit contact</uirouter-sref>
      </uirouter-sref-active>
    </app-drawer>

    <!-- ... -->

    <!-- Main Content -->
    <app-header-layout has-scrolling-region>
      <uirouter-uiview id="mainView"></uirouter-uiview>
    </app-header-layout>

  </template>
</dom-module>

JS part

class MyApp extends Polymer.Element {
  static get is() { return 'my-app'; }

  static get properties() {
    return {
      states: {
        type: Array,
        value: [
          // Pages
          { name: 'contacts', url: '/contacts', abstract: true },
          { name: 'contacts.list', url: '/list', component: 'app-contacts-list' },
          { name: 'contacts.new', url: '/new', component: 'app-contacts-new' },
          { name: 'contacts.edit', url: '/edit', component: 'app-contacts-edit' },

          // Errors
          { name: 'error-404', url: '/not-found', component: 'app-error-404' }
        ]
      },

      // ...
    };
  }
}

window.customElements.define(MyApp.is, MyApp);

Page components are simple HTML views with no behavior at all.

I should precise that the states are not really defined directly in the property, but defined in an external function which is called in the value field of the states property. But the behavior should be the same. Also, maybe I am repeating myself, but the router seems to work as the URL is updated when clicking on a UI-router link, as well as the 'route-active' class on the <uirouter-sref-active> element, and no JS error is thrown. It's just that the content is not injected in the <uirouter-uiview> element.

ergo commented 6 years ago

hey @mknx-io I fixed this in master revision, can you give this a try? I've updated my ui-view demo and it should be working, but https://github.com/ergo/polymer-ui-router/commit/0ae8b3817b72ac91c1ccbd5bdabb37c094e820d4 is most likely incorrect way to resolve this, while this should work I'll try to contact UI Router developer for advice if this can be improved.

mknxdev commented 6 years ago

Hi @ergo, thanks for considering my feedback so quickly and for the fix ;) I'll take a look at your update soon when I'll have some time, and keep you in touch if something happened.

ergo commented 6 years ago

@mknx-io Actually got confirmation from Chris that they also put a blank <ui-view>, so it seems that I've made a proper fix.

ergo commented 6 years ago

Closing this since I made new release with fixes.