2015年再次审视Ember Handling 401s

Con*_*sed 5 error-handling ruby-on-rails ember.js ember-data

在Ember / Ember Data中,我可以从Rails后端找到很多老问题来询问/回答如何处理401。在这一点上,许多(如果不是全部)似乎已经过时了。我已经尽力了。(灰烬数据处理401的

但是,无论我做什么,我都只会在控制台中不断收到401错误,而401s永远不会陷入我的代码中。我要做的就是如果在任何地方/模型/任何地方都遇到401,则将重定向添加到“ /”。我不需要进行身份验证或其他任何检查。

我尝试将其添加到“应用程序路由”操作以及路由器本身。

error: function (error, transition) {
  console.log("err: " + error.status);
  if (error && error.status === 401) {
    return this.transitionToRoute('/');
  }
}
Run Code Online (Sandbox Code Playgroud)

我还尝试了/sf/answers/1334410661/的几种变体。

App.ApplicationAdapter = DS.RESTAdapter.extend({
  ajaxError: function(jqXHR) {
    var error = this._super(jqXHR);
    console.log("jqXHR: " + jqXHR.status);
    if (jqXHR && jqXHR.status === 401) {
      #handle the 401 error
    }
    return error;
  }
});
Run Code Online (Sandbox Code Playgroud)

我显然是菜鸟,所以也许我在这里错过了一些简单的事情。除非是因为我引入了试图使此错误生效的新错误,否则没有任何console.log的触发器被触发。是否有当前的“最佳实践”风格的方法?

jmu*_*yau 1

控制器和路线

对于在控制器或路由中执行的逻辑,通常会有一个error附加到路由的操作。error如果在控制器上触发了一个操作,并且控制器不处理该操作(例如,控制器哈希中没有操作actions),那么它会自动传递到路由以获得处理的机会 - 如果当前路由不处理处理该操作,或者它冒泡到父路由,直到它到达ApplicationRoute.

我处理它的方式是让AuthenticatedRoute任何需要处理 401 的路由都从它延伸。另外,在您链接到的示例中 - 它有events,而现在是actions

像这样的东西应该适合你:

    App.AuthenticatedRoute = Ember.Route.extend({

        actions: {
        error: function(error) {
            if (!error || error.status !== 401) {
                // returning true bubbles the error to parent routes
                return true; 
            }

                // put your logic here
                console.log('this is a 401 error.');
            }
        }

    });

    App.IndexRoute = App.AuthenticatedRoute.extend({
        //logic
    });

    App.FooRoute = App.AuthenticatedRoute.extend({
        //logic
    });

    App.BarRoute = App.AuthenticatedRoute.extend({
        //logic
    });
Run Code Online (Sandbox Code Playgroud)

成分

Ember 越来越倾向于组件 - 在组件中执行的逻辑是它与其他一切完全隔离。一般来说,您在组件中唯一可用的东西就是您传递给它们的东西。

这意味着,如果您在组件中执行某些逻辑,则不会使用上述逻辑(存在于处理错误的路由上的逻辑),除非您自己明确使用它。

store.find('person', 1)如果您在组件中进行类似或类似的调用,person.save()则需要使用该.catch()函数显式处理错误或将第二个函数传递给.then(). 例如,以下两个语句将执行相同的操作:

    store.find('person', 1).then(function(person) {
        console.log('found person 1:', person);
    }, function(err) {
        console.log('error finding person 1:', err);
    });

    store.find('person', 1).then(function(person) {
        console.log('found person 1:', person);
    }).catch(function(err) {
        console.log('error finding person 1:', err);
    });
Run Code Online (Sandbox Code Playgroud)

这两个陈述也是如此:

    person.save().then(function() {
        console.log('successfully saved person');
    }, function(err) {
        console.log('error saving person:', err);
    });

    person.save().then(function() {
        console.log('successfully saved person');
    }).catch(function(err) {
        console.log('error saving person:', err);
    });
Run Code Online (Sandbox Code Playgroud)

在组件中重用路由错误逻辑

如果您想将组件中的错误处理传递到路由上来处理,最好的方法是让组件触发一个操作并让调用模板/视图/控制器处理它。

app/components/my-component.js

    App.AuthenticatedRoute = Ember.Route.extend({

        actions: {
        error: function(error) {
            if (!error || error.status !== 401) {
                // returning true bubbles the error to parent routes
                return true; 
            }

                // put your logic here
                console.log('this is a 401 error.');
            }
        }

    });

    App.IndexRoute = App.AuthenticatedRoute.extend({
        //logic
    });

    App.FooRoute = App.AuthenticatedRoute.extend({
        //logic
    });

    App.BarRoute = App.AuthenticatedRoute.extend({
        //logic
    });
Run Code Online (Sandbox Code Playgroud)

app/templates/components/my-component.hbs

    store.find('person', 1).then(function(person) {
        console.log('found person 1:', person);
    }, function(err) {
        console.log('error finding person 1:', err);
    });

    store.find('person', 1).then(function(person) {
        console.log('found person 1:', person);
    }).catch(function(err) {
        console.log('error finding person 1:', err);
    });
Run Code Online (Sandbox Code Playgroud)

app/templates/index.hbs

    person.save().then(function() {
        console.log('successfully saved person');
    }, function(err) {
        console.log('error saving person:', err);
    });

    person.save().then(function() {
        console.log('successfully saved person');
    }).catch(function(err) {
        console.log('error saving person:', err);
    });
Run Code Online (Sandbox Code Playgroud)