【问题标题】:Ember Route gets stuck after error loading modelEmber Route 在错误加载模型后卡住
【发布时间】:2014-06-25 19:42:34
【问题描述】:

在 ember 路由的模型回调中异步加载数据时,我遇到了一个烦人的问题。问题似乎是,如果我的路线的模型方法返回一个被拒绝的承诺,那么该路线将永远不会尝试重新评估该路线模型。它只是在下次尝试转到该路由时自动返回相同的拒绝承诺,甚至不尝试重新获取数据!

我从this answer 了解到,当尝试将 url 转换为模型时,ember 路由只会调用它的模型方法。我猜想对于带有动态段的路由,如果它以前从未遇到过特定的动态段,则可能会调用它。

这是我的路由器设置。

window.App = Ember.Application.create({
    LOG_TRANSITIONS: true,
    LOG_TRANSITIONS_INTERNAL: true
});

App.Router.map(function() {
    this.route('login');

    this.resource('users', { path: '/users' }, function() {
        this.resource('user', { path: '/:user_id' });
        this.route('create', { path: '/create' });
    });
});

这是我的路线。

App.UserRoute = Ember.Route.extend({
    model: function(params) {
        // This returns a promise
        return App.User.fetch(params.user_id);
    }
});

我对我的应用程序路由中的错误进行了一些特殊处理,以便由于身份验证异常而失败的路由将用户重定向到登录屏幕。

App.ApplicationRoute = Ember.Route.extend({
    actions: {
        sessionExpired: function() {
            this.controllerFor('login').set("tokenExpired", true);
            this.transitionTo('login');
        },
        error: function(err) {
            if (err.type === "TokenException") {
                this.send('sessionExpired');
            }
        }
    }
});

问题

  1. 我导航到/users 路线
  2. 由于某种原因,我的令牌过期(不活动,无论如何...)
  3. 我导航到/users/1 路线
  4. 路由的模型方法返回一个拒绝的承诺,我被踢到登录屏幕
  5. 我重新登录并尝试导航回/users/1 路线
  6. 路由自动返回与上次相同的失败承诺,我被踢出登录屏幕。 :(

我在想,我想要的是在用户登录后清除所有评估过的路线模型的方法。如果这是一个多用户系统并且一个用户注销并且另一个用户在同一台​​计算机上登录而没有刷新页面,那么新用户不应该从前一个用户的会话中自动解析路由。

在我看来,这似乎是一个常见问题,但我找不到任何类型的应用程序范围的无效缓存方法。我该如何解决这个问题?

【问题讨论】:

  • 你看过ember-simple-auth是如何处理这个问题的吗?
  • 为什么不在模型之前检查会话,这样您就不会公然调用您知道会被拒绝的请求?除非底层上下文发生变化,否则模型不会改变。
  • @Beerlington,感谢有关 ember-simple-auth 的建议 - 我会调查一下。
  • @James_1x0,在我要发出 API 请求时,我不知道我的会话是否已通过身份验证。我可以按照您的建议做的唯一方法是在 beforeModel 钩子中发出另一个 API 请求,这意味着在加载任何模型之前等待 API 的往返。我不想这样做,因为我希望应用程序感觉很快。另外 - 这不会解决我的另一个问题,即新用户可以登录并拥有来自以前用户的已解决模型的路线。
  • @RemyD'Agostino 因此,请尝试在调用时更改上下文。使用会话令牌或其他东西。

标签: javascript ember.js


【解决方案1】:

我不确定 ember 数据在缓存清除功能中的位置,但这是一种方法

clearCache: function (type) {
  var map = App.store.typeMapFor(type);
  map.idToCid = {};
  map.clientIds = [];
  map.recordArrays = [];
  map.findAllCache = null;
}

下面是一个示例,说明 ember firebase 库如何使用缓存清除处理失败查找。

  delete store.typeMapFor(store.modelFor('user')).idToRecord[username];

此处的完整示例: https://github.com/firebase/emberFire/blob/master/examples/blog/js/app.js

【讨论】:

  • 对不起斯蒂芬,这对我不起作用。我的 App 对象没有 store 属性 - 可能是因为我没有使用 ember-data 而是手动管理我的模型。
【解决方案2】:

对于发现此问题的任何其他人 - 我从未找到重置 ember 应用程序并使其忘记所有已解决路由的方法。我确实找到了其他一些解决方法。

最后,当用户退出系统或身份验证令牌过期时,我只选择window.reload()

经过身份验证的网址

另一种合理的方法是将随机唯一 id 放入哈希状态。基本上就是这样做。

而不是像这样的路线:

#/contacts/1

为每个经过身份验证的路由加上某种唯一 id

#/PyUE4E+JEdOaDAMF6CwzAQ/contacts/1

App.reset

我尝试了很多东西。我尝试过的更有希望的事情之一是重定向到登录屏幕并在我的全局App 对象上使用应用程序的reset 方法。 http://emberjs.com/api/classes/Ember.Application.html#method_reset

但这不起作用,似乎即使是重置应用程序也会记住它已解决的任何路由的模型 - 很奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多