0

我现在正在开发一个 ember js 应用程序,并且有一个路由结构如下的应用程序:

App.Router.reopen({
    rootURL: '/gui/'
});

App.Router.map(function() {
    this.route("about", { path: "about"})
    this.resource("tenant", { path: ":id" }, function() {
        this.resource("dossier", { path: "dossiers/:id"}, function() {
            this.resource("resource", { path: "resources/:id"}, function() {
                this.resource("service", { path: "services/:id"});
            });
        });
    })
});

现在,在最深层的模型(服务)上,当我尝试通过键入 URL 来加载服务时,它会失败。所以,如果我去,例如, http://localhost:8080/gui#/8080/dossiers/8080/resources/8080/services/8080我得到一个错误:

Assertion failed: Cannot call get with 'id' on an undefined object.

我想,也许是我生成模型的代码有问题,但我把所有代码都去掉了,把模型作为一个裸函数,只是为了看看,它仍然给出这个错误。但是,如果我完全从路线中删除模型代码,它将加载页面而不会抱怨。所以这:

App.ServiceRoute = Ember.Route.extend({
    model: function(params) {},
    renderTemplate: function() {
        this.render('service', {
            into: 'application'
        });
        this.render()
    }
});

引发错误。与原始代码一样:

App.ServiceRoute = Ember.Route.extend({
    model: function(params) {
        tenantModel = this.modelFor('tenant');
        dossierModel = this.modelFor('dossier');
        resourceModel = this.modelFor('resource');
        dossier_url = "/api/" + tenantModel.id + "/dossier/" + dossierModel.tag
        url = dossier_url + "/resources/" + resourceModel.name + "/services/" + params.id
        return jQuery.getJSON(url).then(function(data){
            data
        });
    },
    renderTemplate: function() {
        this.render('service', {
            into: 'application'
        });
        this.render()
    }
});

但是,如果我像这样取出模型:

App.ServiceRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render('service', {
            into: 'application'
        });
        this.render()
    }
});

然后错误消失。

这是最奇怪的部分。

如果我加载不同的页面,然后导航到服务页面......它可以工作。它加载模型就好了。只是如果我尝试刷新页面,或者将服务的 url 直接放入浏览器,它就会出错。

我阅读了有关此错误的各种互联网帖子,但似乎没有一个与我所看到的情况相匹配 - 尝试调整这个和那个,仍然没有。有任何想法吗?

4

1 回答 1

1

我想以下可以使它工作:

App.ServiceRoute = Ember.Route.extend({
    model: function(params) {
        tenantModel = this.modelFor('tenant');
        dossierModel = this.modelFor('dossier');
        resourceModel = this.modelFor('resource');
        dossier_url = "/api/" + tenantModel.id + "/dossier/" + dossierModel.tag
        url = dossier_url + "/resources/" + resourceModel.name + "/services/" + params.id

        var promise = Ember.Deferred.create();
       jQuery.getJSON(url).then(function(data){
            promise.resolve(data);
        });

        return promise;
    },
    ....
});

关于您的问题的一些评论:

为什么它会说:“断言失败:无法在未定义的对象上使用 'id' 调用 get。”?

在您的示例中,模型挂钩的实现不执行任何操作。所以返回值是未定义的。调用模型挂钩后,Ember 似乎再次尝试更新 URL。您的映射说它应该使用路由模型的 id 来执行此操作。因此它会尝试获取未定义对象的 id 属性。

为什么导航到服务页面时它会起作用?

我猜在这种情况下,您正在为您的路线提供一个模型,其中包含一个{{link-to}}助手或调用transitionTo. 如果您提供模型,则不需要调用您路线的模型钩子。当您通过 URL 输入您的应用程序时,必须执行模型挂钩。

我的解决方案如何运作?

您正在通过 jQuery.getJSON 进行异步调用。当您的代码到达模型挂钩的末尾并因此再次返回未定义时,此请求尚未完成。相反,我返回一个承诺。Ember 正在等待这个承诺得到解决。我在 jQuery.getJSON 的回调中解决它。

PS:我不确定您对 jQuery.getJSON 的调用是否正确。它是否必须调用成功函数。但我不是 jquery 专家,这可能是完全错误的 :-)

于 2013-11-06T18:30:33.090 回答