问题 Ember JS转换到嵌套路由,其中​​所有路由都是视图中的动态段


我们正在使用EmberJS编写应用程序。然而,我们仍然是这个框架的新手,我们很难解决一些看似直截了当的事情。

该模型非常简单,有3个模型:Queue,Task和Image。我们对所有路径使用动态URI段,这些模型的路由嵌套在以下形式中: :queue_id /:TASK_ID /:image_id。

路由配置方式如下:

App.Router.map(function() {
   this.resource('queue', {path: ':queue_id'}, function() {
      this.resource('task', {path: ':task_id'}, function() {
         this.resource('image', {path: ':image_id'});
      });
   });
}

在HTML的某个地方,我们有这个简单的模板来迭代任务中的所有图像:

{{#each task.images}}
   <li>
      {{#view App.ThumbnailView.contentBinding="this"}}
         <img {{bindAttr src="thumbnail.url"}} />
      {{/view}}
   </li>
{{/each}}

以下是缩略图视图的代码:

App.ThumbnailView = Ember.View.extend({
   tagName : 'a',
   click : function(e) {
       var task = //assume this value exists;
       var queue = //assume this value exists;
       var image = //assume this value exists;

       this.get('controller.target.router').transitionTo('image', queue, task, image);
   }
});

最后,这是我们的ImageRoute:

App.Image = Ember.Object.extend();
App.Image.reopenClass({
    find : function(image_id) {
       //This is where I set a breakpoint
       console.log(image_id);
    }
});

App.ImageRoute = Ember.Route.extend({
    model : function(params) {
      //image_id is the last uri segment in: #/1/1/1
      return App.Image.find(params.image_id);
    }
});

问题: 打电话给 this.get('controller.target.router').transitionTo() 好像在起作用。我可以看到,当我点击其中一个缩略图视图时,URL会发生变化(例如从/ 1/1/2更改为/ 1/1/3)。但是,我没有看到UI中的状态发生任何变化。此外,我放置断点的行似乎没有被触发。但是当我刷新页面时,它运行良好。

我的转换代码有问题吗?

谢谢。


3381
2018-05-10 07:08


起源



答案:


有两点需要注意:

首先,而不是

this.get('controller.target.router').transitionTo('image', queue, task, image);

使用:

this.get('controller').transitionToRoute('image.index', queue, task, image);

这可能不会改变行为,但它更像是Ember惯用语。

第二件事如下:

内部过渡不会触发 model 挂钩在路线上,因为Ember假设你正在传递模型以及过渡,所以不需要调用 model 因为你已经通过了模型。

这就是你的断点没有被触发的原因 find 没有被调用(因为它不应该)。

我没有足够的信息来查找您的问题,但如果我猜测页面刷新是否有效,而内部转换不是因为传递给的对象之间存在不一致 transitionTo 以及从...返回的内容之间 model 钩。

你应该将确切的对象传递给 transitionTo 作为那些本来可以归还的model 钩。

如果你这样做:

this.get('controller').transitionToRoute('image.index', queue, task, image);

并且它不起作用,也可能是错误的 queuetask, 要么 image 你传递的模特。

所以这:

   var task = //assume this value exists;
   var queue = //assume this value exists;
   var image = //assume this value exists;

不是很有帮助,因为它可能是问题所在。


13
2018-05-10 10:25



嗨泰迪。谢谢。你是对的,从模型钩子返回的模型与我传递的模型不同。有没有办法从ThumbnaiView获得ImageRoute的模型? - arjaynacion
您无需调用实际的ImageRoute model 钩子,你需要传递相同的模型 仿佛 它是从模型钩子返回的。你正在循环 task.images,这不是一个数组 App.Image 模型实例(与从ImageRoute模型钩子返回的相同)? - Teddy Zeenny
好,谢谢。现在我想我知道该怎么做。但由于我的路由都是动态段,/ queue_id / task_id / image_id,这是否意味着我需要通过其ID重新查询队列和任务,然后在transitionToRoute方法中传递这些模型?我在想是否有办法获得这些模型而不必重新查询。例如在任何路由中,我可以使用调用this.modelFor('routeName')来获取该路由的模型。在一种观点中,我认为这是不可能的。 - arjaynacion
我试着在这里重现你的应用: jsfiddle.net/teddyzeenny/kZqkx 希望它会给你一些如何进行的想法。 - Teddy Zeenny
谢谢泰迪。我明天早上回去工作时会先尝试这件事。 - arjaynacion


答案:


有两点需要注意:

首先,而不是

this.get('controller.target.router').transitionTo('image', queue, task, image);

使用:

this.get('controller').transitionToRoute('image.index', queue, task, image);

这可能不会改变行为,但它更像是Ember惯用语。

第二件事如下:

内部过渡不会触发 model 挂钩在路线上,因为Ember假设你正在传递模型以及过渡,所以不需要调用 model 因为你已经通过了模型。

这就是你的断点没有被触发的原因 find 没有被调用(因为它不应该)。

我没有足够的信息来查找您的问题,但如果我猜测页面刷新是否有效,而内部转换不是因为传递给的对象之间存在不一致 transitionTo 以及从...返回的内容之间 model 钩。

你应该将确切的对象传递给 transitionTo 作为那些本来可以归还的model 钩。

如果你这样做:

this.get('controller').transitionToRoute('image.index', queue, task, image);

并且它不起作用,也可能是错误的 queuetask, 要么 image 你传递的模特。

所以这:

   var task = //assume this value exists;
   var queue = //assume this value exists;
   var image = //assume this value exists;

不是很有帮助,因为它可能是问题所在。


13
2018-05-10 10:25



嗨泰迪。谢谢。你是对的,从模型钩子返回的模型与我传递的模型不同。有没有办法从ThumbnaiView获得ImageRoute的模型? - arjaynacion
您无需调用实际的ImageRoute model 钩子,你需要传递相同的模型 仿佛 它是从模型钩子返回的。你正在循环 task.images,这不是一个数组 App.Image 模型实例(与从ImageRoute模型钩子返回的相同)? - Teddy Zeenny
好,谢谢。现在我想我知道该怎么做。但由于我的路由都是动态段,/ queue_id / task_id / image_id,这是否意味着我需要通过其ID重新查询队列和任务,然后在transitionToRoute方法中传递这些模型?我在想是否有办法获得这些模型而不必重新查询。例如在任何路由中,我可以使用调用this.modelFor('routeName')来获取该路由的模型。在一种观点中,我认为这是不可能的。 - arjaynacion
我试着在这里重现你的应用: jsfiddle.net/teddyzeenny/kZqkx 希望它会给你一些如何进行的想法。 - Teddy Zeenny
谢谢泰迪。我明天早上回去工作时会先尝试这件事。 - arjaynacion