在Ember.js 4之前的直接网址访问中填充内容

时间:2013-02-12 16:21:50

标签: javascript ember.js ember-router

摆弄大多数工作代码:http://jsfiddle.net/VDA2p/16/

路线摘录相信问题所在:

// #/listings/:listing_id/videos
App.VideosRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('listing');
    }
});

如果我选择“视频”链接,则网址为“/ listings / 1 / videos”(例如),我的内容加载就好了。如果我通过地址栏直接访问此网址,则不会检索任何视频。我一直在玩serialize()的调用,但无法使它工作,我不确定我是否在正确的道路上。我也注意到,一旦我直接访问网址并且没有获取视频,如果我直接转到'/ listing'网址(加载内容很好)并选择任何“视频”链接,视频内容为不再为任何条目加载。但是,如果我在'/ listings'网址上刷新我的浏览器/应用,那么内容就会出现在“视频”链接下。

更新1:

如果我将上面的原始代码段更改为

// #/listings/:listing_id/videos
App.VideosRoute = Ember.Route.extend({
    model: function(params) {
    return App.Listings.find(params.listing_id);
    }
});

它按预期工作,虽然我不明白为什么。

更新2:

但确实打破了“观看视频”链接,但直接访问了“/ listings / 1 / videos”网址,而不是通过链接。它现在显示为'/ listings / null / videos / 1',即使您点击它时单个视频加载就好了。使用后退按钮可以返回'/ listings / 1 / videos',其中所有“观看视频”链接中不再包含“空”。

例如,尝试直接转到'/ listings / 1 / videos / 2'url会引发错误“错误:断言失败:您在路由器中使用了动态段video_id,但App.Video没有存在并且您没有覆盖州的model挂钩。“我现在也在努力追捕。选择“查看视频”链接会很好地加载数据。

1 个答案:

答案 0 :(得分:4)

jsFiddle example

您要做的是使用嵌套路由结构。这允许每个嵌套级别在评估路由时进行序列化/反序列化。

例如,如果您直接输入网址/listings/1/videos/2,则会调用App.ListingsRoute的方法,然后调用App.ListingRoute,然后调用App.VideosRoute,然后终于App.VideosVideoRoute了。在您的旧路由器中,平面性质不允许正确处理网址部分/listings/listings/:listing_id,从而导致您看到的错误。

由于添加了嵌套,模板和路径的某些名称与原始示例略有不同。如果您想了解有关嵌套路由的命名方案的更多详细信息,请查看emberjs routing docs

代码的renderTemplate部分告诉ember将模板呈现为{{outlet}}路由提供的application。默认设置是假设每个嵌套路由中都有嵌套的{{outlet}}

路由器:

App.Router.map(function() {
    this.resource('listings', function() {
        this.resource('listing', { path: '/:listings_id' }, function(){
            this.resource('videos', function() {
                this.route('video', { path: '/:videos_id' });
            });
        });
    });
});

路线:

// #/index
App.IndexRoute = Ember.Route.extend({
    redirect: function(){
            this.transitionTo('listings');
    }
});

// #/listings
App.ListingsIndexRoute = Ember.Route.extend({
    model: function() {
        return App.Listings.find();
    },
    renderTemplate: function() {
        this.render({into: 'application'});   
    }
});

// #/listings/:listing_id
App.ListingRoute = Ember.Route.extend({});

// #/listings/:listings_id/videos
App.VideosIndexRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('listing').get("videos");
    },
    renderTemplate: function() {
        this.render({into: 'application'});   
    }
});

// #/listings/:listings_id/videos/:videos_id
App.VideosVideoRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render({into: 'application'});   
    }
})