简体   繁体   中英

Polymer route/iron-pages not working?

I am just trying out Polymer 1.0. I find that app-route / iron-pages is not working. Navigating between routes does not appear to show the correct view. Not sure which part went wrong:

In the main file:

<app-drawer-layout>
  <app-location route="{{route}}"></app-location>

  <app-route
    route="{{route}}"
    pattern="/:view"
    data="{{routeData}}"
    tail="{{subroute}}"></app-route>

  <app-drawer>
    <main-drawer></main-drawer>
  </app-drawer>

  <app-header-layout>
    <app-header>
      <paper-toolbar>
        <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
        <div class="title">
          Expenses App
        </div>
      </paper-toolbar>

      <iron-pages selected="[[view]]">
        <expenses-dashboard name="dashboard" route="{{subroute}}"></expenses-dashboard>
        <expenses-settings name="settings" route="{{subroute}}"></expenses-settings>
      </iron-pages>
    </app-header>
  </app-header-layout>
</app-drawer-layout>

In side both expenses-dashboard and expenses-settings is just placeholder content like:

<link rel="import" href="../../bower_components/polymer/polymer.html">

<dom-module id="expenses-dashboard">
  <template>
    <h1>Dashboard</h1>
  </template>

  <script>
    Polymer({
      is: 'expenses-dashboard'
    });
  </script>
</dom-module>

For <iron-pages selected="[[view]]"> , should I be using routeData.view or view ? I tried both didnt seem to change anything.

The code on GitHub

There are a few issues in your code...

  1. Since your <iron-pages>.selected property is bound to an undefined property ("view"), <iron-pages> does not change its page. In your <app-route> data binding, the route parts are parsed into routeData , where the :view slug would be accessed with routeData.view , which is what you should be binding to <iron-pages>.selected :

     <iron-pages selected="[[routeData.view]]"> 
  2. The default selector for <iron-pages> is the page index (ie, the child index of its contents), so selected would normally have to be an integer between 0 and N - 1 inclusively, where N is the number of child pages. But you could change that. It looks like you want the route to specify the page, which would need to match the name of a page under <iron-pages> . To use "name" as the selected attribute, you'd have to configure <iron-pages>.attrForSelected property :

     <iron-pages selected="foo" attr-for-selected="name"> <div name="foo"></div> <div name="bar"></div> </iron-pages> 

    It might also be a good idea to specify a fallback selection , since the user could accidentally navigate to a URL that doesn't correspond to an existing page (eg, https://mypage.com/#/non-existent-page ).

     <iron-pages selected="[[routeData.view]]" attr-for-selected="name" fallback-selection="foo"> <div name="foo"></div> <div name="bar"></div> </iron-pages> 
  3. In <main-drawer> , you may want to define menuTap() with ES5 syntax (instead of ES6) for maximum browser compatibility.

     Polymer({ // menuTap(e) { ... } // <-- ES6 menuTap: function(e) { ... } }); 
  4. Your menuTap() function sets the window.location to a raw path, which noticeably refreshes the page. You could avoid the page refresh by using hash paths, where the intended sub-path of the URL is prefixed with a # (eg, https://mypage.com/#/settings ).

    For hash paths, configure <app-location> to ignore the hash prefix by setting the useHashAsPath property :

     <app-location use-hash-as-path route="{{route}}"> 

    If you prefer to avoid hash paths, you could follow Polymer CLI's app-drawer-template , which uses anchor tags inside an <iron-selector> to set the location, which <app-location> detects and updates its route accordingly. Or you could pass the route in from <expenses-app> and then use this.set('route.path', "dashboard") inside of menuTap() .

With the changes above, the following would occur when the user navigates to https://mypage.com/#/dashboard .

  1. <app-location> would set the route property to /dashboard .
  2. <app-route> would parse the route and set routeData.view to dashboard .
  3. <iron-pages> sees routeData.view as dashboard , which matches the specified attribute on a child, which in turn causes only that page to be displayed.

For reference, the guide on Encapsulated Routing with Elements is quite useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM