如何在Polymer中从视图内部更改路径?

时间:2016-12-02 10:55:57

标签: polymer

在Polymer中的简单路由配置中,就像从starter-kit获得的那样:

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

<app-drawer-layout fullbleed>
  <!-- Drawer content -->
  <app-drawer>
    <app-toolbar>Menu</app-toolbar>
    <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
      <a name="view1" href="/view1">View One</a>
      <a name="view2" href="/view2">View Two</a>
      <a name="view3" href="/view3">View Three</a>
    </iron-selector>
  </app-drawer>

  <!-- Main content -->
  <app-header-layout has-scrolling-region>

    <app-header condenses reveals effects="waterfall">
      <app-toolbar>
        <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
        <div main-title>My App</div>
      </app-toolbar>
    </app-header>

    <iron-pages
        selected="[[page]]"
        attr-for-selected="name"
        fallback-selection="view404"
        role="main">
      <my-view1 name="view1"></my-view1>
      <my-view2 name="view2"></my-view2>
      <my-view3 name="view3"></my-view3>
      <my-view404 name="view404"></my-view404>
    </iron-pages>
  </app-header-layout>
</app-drawer-layout>

带有按钮的视图,如果按下该按钮,则应更改路径,如下所示:

<dom-module id="my-view1">
  <template>
      <paper-button raised on-tap="changeRoute">Change route</paper-button>
  </template>

  <script>
    Polymer({
      is: 'my-view1',

      changeRoute() {
          // How to change route here?
      }
    });
  </script>
</dom-module>

如何在上面的事件处理程序中以编程方式更改路由?我试着改变window.location没有成功(我在Electron内部,不确定它是否是问题的一部分)。

从Polymer docs,关于改变路线:

  

更新路线。路由对象是读写的,因此您可以使用   双向数据绑定或this.set更新路由。两条路线   和routeData对象可以这种方式操作。例如:

     

this.set('route.path','/ search /');

     

或者:

     

this.set('routeData.user','mary');

但是如果在主要组件(定义路由的那个)内完成,这是正确的(并且有效),而如果在视图中调用它则不起作用。提出这个问题的另一种方法可能是:如何从内部组件访问主路由器对象?

5 个答案:

答案 0 :(得分:3)

嗯。原来并不是那么困难:

\d+

其中main-window是定义路由的容器组件(第一个源文件)。

有没有人对这个问题有更好/更一般的方法?

答案 1 :(得分:2)

有几种方法可以做到这一点,我可能已经过火但我开始进入它所以这里...

根据您给出的答案,您似乎只想“回去”。如果是这种情况,你可以使用

history.back();

或者,如果你想转向一条新路径,那么更强大,包括更多SEO友好的方法(我相信)是使用类似的东西:

<a href="/newpath" tabindex="-1">
   <paper-button>Change Route</paper-button>
</a>

或者@Carlos的答案也有效,但应用程序路线“哲学”似乎更多的是允许分散路由方法&amp;所以传递一个事件让另一个组件处理这条路线感觉有点像是对抗谷物。虽然不一定是这种情况,因为组件可以非常简单,可能只是一个按钮,图标等,因此您可能希望由父元素处理路由。在这种情况下,虽然看起来你的组件是一个完整的视图,所以我更倾向于它可能会处理路由本身。

我也会在@ tony19的回答中说出类似上面的内容。

我认为这个方法在你自己的答案中最大的缺点是你正在挖掘另一个元素的内涵,所以你已经与它紧密耦合了。绝对不推荐那个。

哦&amp;另一种改变路线的方法:

window.history.pushState({}, null, '/new_path');
window.dispatchEvent(new CustomEvent('location-changed'));

这是在这里给出的 - https://github.com/PolymerElements/app-route#integrating-with-other-routing-code但这对于处理其他路由代码或特殊情况&amp;在你的情况下会非常黑客。

答案 2 :(得分:1)

我遇到了同样的问题,并且通过将路由元素添加到视图中来解决它:

<app-location route="{{route}}"></app-location>
<app-route route="{{route}}" pattern="/app/:view" data="{{routeData}}" tail="{{subRoute}}"></app-route>
<app-route route="{{subRoute}}" pattern="/:id" data="{{idData}}" active="{{onDetailPage}}"></app-route>

然后您可以在元素中更改路径,如下所示:

this.set("route.path", "/app/foo");

答案 3 :(得分:0)

您的“view1”可能会触发一个自定义事件,该事件会触发您应用中的路线更改。

这将遵循以下建议的观察者模式:Thinking in Polymer (The Polymer Summit 2015)

注意:this问题的答案也可能对您有帮助。

答案 4 :(得分:0)

您可以使用app-location元素的路径属性轻松完成此操作:

changeRoute() {
  var $router = this.shadowRoot.querySelector("app-location");

  $router.path = "/view1";
}

此处元素的文档app-location

设置路径属性将启动路径更改事件...这将开始事件级联到 iron-pages 元素并切换视图。