Ember Handling 401s Revisited in 2015 [英] Ember Handling 401s Revisited in 2015

查看:92
本文介绍了Ember Handling 401s Revisited in 2015的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以从Ember / Ember Data中的Rails后端找到一大堆老问题,询问/回答如何处理401s。在这一点上,许多(如果不是全部)似乎已经过时了。我已经尝试过我能找到的一切。 ( Ember-Data handling 401's



但是不管我做什么,我只是在控制台中不断得到401错误,而401代码从来没有在我的代码中被捕获。所有我想要做的是添加一个重定向到'/',如果在任何地方/模型/任何东西遇到一个401。我不需要任何检查身份验证或其他任何东西。



我已经尝试将此添加到应用程序路由操作以及路由器本身。

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

我也尝试过这种 https://stackoverflow.com/a/19063009/1850353

  App.ApplicationAdapter = DS.RESTAdapter.extend({
ajaxError:function(jqXHR){
var error = this._super(jqXHR);
如果(jqXHR&& jqXHR.status === 401){ $ b return error;
}
});

我显然是一个noob,所以也许我在这里缺少一些简单的东西。除非我出现了一个新的错误,否则我的console.log不会被触发,因为我试图让这个工作正常。

解决方案

控制器和路由



对于在控制器或路由中执行的逻辑,您通常会在路由上附加一个错误操作。如果在控制器上触发一个动作,并且控制器没有处理该动作(例如控制器操作中没有错误操作 hash),那么它会自动传递给路由以获得一个机会来处理 - 如果当前路由不处理动作,否则它会冒泡到父路由,直到它碰到 ApplicationRoute



我处理它的方式是有一个 AuthenticatedRoute 需要处理的任何路由一个401从。此外,在您链接的示例中 - 它有事件,而现在是操作



这样的东西应该适合你:

  App.AuthenticatedRoute = Ember.Route。 extend({

actions:{
error:function(error){
if(!error || error.status!== 401){
//返回真实气泡的错误到父路由
返回true;
}

//把你的逻辑在这里
console.log('这是一个401错误。 );
}
}

});

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

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

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



组件



Ember正在移动更多,更多的组件 - 在组件中执行的逻辑的事情是它完全与其他所有的隔离。通常,您的组件中唯一可用的东西就是您传递给它们的东西。



这意味着如果您在组件中执行某些逻辑,那么逻辑以上 - 存在于处理错误的路由上的逻辑 - 被使用,除非您自己明确使用它。



如果您打电话像存储。您需要使用<$ c $()显式处理错误的组件中找到('person',1) person.save() c> .catch()函数或将第二个函数传递给 .then()。例如,以下两个语句将执行相同的操作:

  store.find('person',1).then(function (人){
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 find person 1:',err);
});

这两个语句也是这样:

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

person.save()然后(function(){
console.log('successfully saved person');
})。catch(function(err){
console.log('error saved person:',err);
});



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



如果要将您的组件中的错误处理传递到路由上以处理最佳方法,则该组件将触发一个动作,并使调用模板/视图/控制器处理它。



app / components / my-component.js

'on-error':null,
model:null,
actions:{
save :function(){
var component = this;
var model = this.get('model');

mode.save()然后(function()
console.log('saved');
})。catch(function(err){
component.sendAction('on-error',err);
}) ;
}
}
});

app / templates / components / my-component.hbs

 < button {{action'save'}}> Save<按钮> 

app / templates / index.hbs / p>

 <! -  
将错误操作传递给组件-error'属性将组件上的'on-error'
操作与控制器上的'error'操作相链接 - 如果控制器
没有处理它,它将冒泡到路由处理
- >

{{my-component model = model on-error ='error'}}


I can find a ton of old questions asking/answering how to handle 401s from the Rails backend in Ember/Ember Data. Many, if not all, seem to be outdated at this point. I have tried everything I could find. (Ember-Data handling 401’s)

But no matter what I do I just keep getting 401 errors in the console while the 401s are never caught in my code. All I want to do is add a redirect to '/' if a 401 is ever encountered in any place/model/anything. I don't need any checking for authentication or anything else.

I have tried adding this to the Application Route actions as well as to to the Router itself.

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

I've also tried several variations of this https://stackoverflow.com/a/19063009/1850353.

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;
  }
});

I'm obviously a noob so maybe I'm missing something simple here. None of my console.log's are getting triggered unless it's for a new error I've introduced trying to get this to work. Is there a current, 'best practice' style way of doing this?

解决方案

Controllers and Routes

With logic that is executed in a controller or route, you generally have an error action attached to the route. If an action is triggered on a controller and the controller doesn't handle that action (e.g. there is no error action in the controllers actions hash) then it is automatically passed to the route to get a chance to handle - if the current route doesn't handle the action either it bubbles to parent routes until it hits the ApplicationRoute.

The way I handle it is have an AuthenticatedRoute that any route that needs to handle a 401 extends from. Also, in the example you've linked to - it has events whereas it's now actions.

Something like this should work for you:

    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
    });

Components

Ember is moving more and more towards components - the thing with logic executed in components is that it's completely isolated from everything else. Generally the only things available to you in your components are the things you pass into them.

This means that if you're executing some logic in a component none of the logic above - the logic that exists on the routes to handle errors - is used unless you explicitly use it yourself.

If your making calls like store.find('person', 1) or person.save() in a component you need to handle the errors explicitly using the .catch() function or passing a second function to the .then(). For example the following two statements would do the same thing:

    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);
    });

And so would these two statements:

    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);
    });

Reusing the Route Error Logic in Components

If you want to pass the error handling in your components onto your routes to deal with the best way to do that is have the component fire an action and have the calling template/view/controller handle it.

app/components/my-component.js

    Ember.Component.extend({
        'on-error': null,
        model: null,
        actions: {
            save: function() {
                var component = this;
                var model = this.get('model');

                mode.save().then(function() {
                    console.log('saved');
                }).catch(function(err) {
                    component.sendAction('on-error', err);
                });
            }
        }
    });

app/templates/components/my-component.hbs

    <button {{action 'save'}}>Save</button>

app/templates/index.hbs

    <!-- 
        Passing the 'error' action to the components 'on-error' property links the 'on-error' 
        action on the component with the 'error' action on the controller - if the controller 
        doesn't handle it, it's bubbled up to the route to handle
    -->

    {{my-component model=model on-error='error'}}

这篇关于Ember Handling 401s Revisited in 2015的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆