如何维护页面状态,以便使用emberjs提供永久链接

How do you maintain the page state, so that you can provide permalinks using emberjs?

本文关键字:emberjs 链接 何维护 维护 状态      更新时间:2023-09-26

我不知道你是如何支持永久链接的。这可能只是因为emberjs不支持永久链接。

我正在构建一个用户界面,允许用户选择某些报告,所以在ember中,这很容易,你只需添加一个带有id的路由"报告",URL看起来像这样:

#/reports/10/

我需要的是一些额外的参数也出现在该URL中,例如开始和结束日期以及度量类型,例如

#/reports/10/metric/impressions/start/10-08-2013/end/11-08-2013

因此,如果我将这些参数粘贴到浏览器中,就需要提取这些参数,重要的是,当用户更改这些设置时,例如通过日期选择器,URL应该更新以反映新的参数。

编辑:

这里有一个指向jsbin的链接,该链接提供了基于以下答案的解决方案。http://jsbin.com/ucanam/703

只是把我的2美分投入到这个主题中。请注意,我在生产中使用这种方法,效果很好。实际上,这个问题有两个部分。

1.如何拥有多个动态分段

Mike Grasotti使用嵌套资源描述了一种方法。这种方法有效,但我认为这种方法在这种情况下有点麻烦。

为什么我觉得它很麻烦

路线是Ember中分离关注点的一种方式。在这种情况下,我没有看到单独的担忧。在我看来,你似乎在试图镜像URL中表单的状态。我认为这应该是一条对关注"形式状态"负责的途径。因此,我建议看一看下面的帖子,我在帖子中描述了如何实现每个路由的多个动态参数:资源嵌套是启用多个动态分段的唯一方法吗?

2.当您只更改了表单中的一个参数时,如何触发序列化挂钩来更新URL

问题是,只有当使用新模型输入Route时,才会触发serialize hook。我想您已经准备好了一些逻辑,用于处理更改参数startend的事件。在这种情况下,我想你不会重新进入路线。那么,在这种情况下,如何再次触发序列化挂钩来更新URL呢?我正在我的路由器中处理这样的事件,我在那里使用以下代码:

var currentRouteName = this.controllerFor("application").get("currentPath");//the ApplicationController stores the name of the current Route
var url = App.Router.router.generate(currentRouteName);
App.Router.router.updateURL(url);

附言:您可以在此处查看我的生产应用程序。此应用程序可在德国影院播放最好的电影。即使你不懂德语,你也可以点击顶部区域的一个控件,看到URL正在更新。我想这和你想要的差不多吧?

我也想知道如何做到这一点。数据必须放在URI中,因为我们想要共享链接,但您不想将应用程序位置与应用程序状态混淆。

hash:#/reports/10将是告诉应用程序去哪里所需的最小信息。所有其他与位置无关的数据可能都应该进入URI的搜索部分。我建议这样做:

#/reports?metrics=impressions&start=10-08-2013&end=11-08-2013

理论上,您可以在输入路线时解析查询字符串,然后相应地更新模型。根据我的理解,当导航到一条路线时,通过直接更改URL或单击链接来调用路线的model()函数,使其成为该位置。

不幸的是,在实践中,这并没有像我预期的那样奏效。我不确定它是否只是JSBin,但有一些奇怪的行为,带有额外应用程序数据的链接实际上并没有导航,这就是永久链接的全部意义。请注意,如果您遵循JSBin中的指示,则开始日期和结束日期将取自url,而不是默认值。这个概念可以扩展为使用findQuery等发送对不同模型数据的额外请求,所以几乎任何事情都是可能的。

http://jsbin.com/abadet/7

无论如何,它可能会给你一些想法。

有几种方法可以在ember中完成这项工作。如果您需要为可能传递到报表的其他参数提供很大的灵活性,请查看ember查询,它为ember应用程序添加了查询字符串支持。

另一种选择是使用嵌套资源。例如:

App = Ember.Application.create({});
App.Router.map(function() {
  this.resource('report', {path: '/reports/:report'}, function() {
    this.resource('metric', {path: '/:metric'}, function() {
      this.resource('start', {path: '/:start'}, function() {
        this.route('end', {path: '/:end'});
      });
    });
  });
});
App.StartEndRoute = Ember.Route.extend({
  model: function(params, transition){
    return transition.params
  }
});
<script type="text/x-handlebars" data-template-name="start/end">
<pre>
Report ID: {{report}}
metric: {{metric}}
start: {{start}}
end: {{end}}
{{log this}}
</pre>
</script>

有关的工作示例,请参阅此jsbin