Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在XHR请求中保持作用域?_Javascript_Scope_Xmlhttprequest_Url Routing - Fatal编程技术网

Javascript 如何在XHR请求中保持作用域?

Javascript 如何在XHR请求中保持作用域?,javascript,scope,xmlhttprequest,url-routing,Javascript,Scope,Xmlhttprequest,Url Routing,因此,我正在构建一个Javascript路由器,并构建一条如下所示的路由: route('/user/{name}', 'page', function() { this.text = 'User: ' + this.name; }); var that = this; 函数的作用域是当前路由,因此我可以在这里操作当前路由(this.text是视图所要查找的) 现在,我的下一步是在路由中包含一个XHR请求,它看起来像: route('/user/{name}', 'page', fu

因此,我正在构建一个Javascript路由器,并构建一条如下所示的路由:

route('/user/{name}', 'page', function() {
    this.text = 'User: ' + this.name;
});
var that = this;
函数的作用域是当前路由,因此我可以在这里操作当前路由(this.text是视图所要查找的)

现在,我的下一步是在路由中包含一个XHR请求,它看起来像:

route('/user/{name}', 'page', function() {
    this.text = 'Loading';

    var request = new XMLHttpRequest();
    request.open('GET', '/api/user', true);

    request.onreadystatechange = (function() {
        if (this.readyState === 4) {
            if (this.status >= 200 && this.status < 400) {
                var data = JSON.parse(this.responseText);
                // here is the issue: 'this' now refers to
                // the XHR request and not the scope of the router
                this.age = data.age;
                this.gender = data.gender;
            } else {
                this.text = "Error";
            }
        }
    })/* .bind(this); */ // keeping scope like this overwrites the XHR

    request.send();
    request = null;
});
route('/user/{name}',page',function(){
this.text='Loading';
var request=new XMLHttpRequest();
open('GET','/api/user',true);
request.onreadystatechange=(函数(){
if(this.readyState==4){
如果(this.status>=200&&this.status<400){
var data=JSON.parse(this.responseText);
//问题是:“这个”现在指的是
//XHR请求,而不是路由器的作用域
this.age=data.age;
this.gender=data.gender;
}否则{
this.text=“Error”;
}
}
})/*.bind(this);*///这样保留作用域会覆盖XHR
request.send();
请求=null;
});
这里的问题是我需要访问XHR范围和我的路由器范围。在onreadystatechange的末尾使用.bind会覆盖XHR范围,而不设置它会覆盖路由器的范围

那你怎么办?是否有比
var=this更干净的东西--肯定有办法吗?

那么:

route('/user/{name}', 'page', function() {
    var routeScope = this;

    request.onreadystatechange = (function() {
        if (this.readyState === 4) {
            if (this.status >= 200 && this.status < 400) {
                console.log(this);
                // "this" is xhr's scope, while 
                console.log(routeScope);
                // routeScope is your router's scope
                // ...
            }
        }
    });
})
route('/user/{name}',page',function(){
var routeScope=this;
request.onreadystatechange=(函数(){
if(this.readyState==4){
如果(this.status>=200&&this.status<400){
console.log(this);
//“这”是xhr的范围,而
控制台日志(routeScope);
//routeScope是路由器的作用域
// ...
}
}
});
})
编辑:嗯,读一下你的最后一句话。。。无需担心。

最简单(也是非常清楚的方法)是将对route范围的引用保持如下:

route('/user/{name}', 'page', function() {
    this.text = 'User: ' + this.name;
});
var that = this;
您还可以使用
.bind()
设置范围,并直接从
reqest
变量访问请求属性

对于您的示例(使用
bind
helper函数,以支持旧浏览器):

var bind=function(fn,上下文){
返回函数(){
fn.应用(上下文、参数);
};
};
request.onreadystatechange=bind(函数(){
if(request.readyState==4){
如果(request.status>=200&&request.status<400){
var data=JSON.parse(request.responseText);
this.age=data.age;
this.gender=data.gender;
}否则{
this.text=“Error”;
}
}
},这个);

this
不能从
this.age
this.gender
中删除
this
?为什么不:
var that=this?这可能不是最优雅的方式,但它是有效的…这只是我的问题,有没有更干净的方式来保持范围。Buuut我想没有办法避免它,因为'this'将与'this'一起分类,也许解决方案是设置默认范围变量的一种方法。谢谢@ChrisL和maze le@ChrisL不,它会报告“年龄”/“性别”没有定义。控制器函数的调用方式如下:
route.controller.apply(数据)谢谢,我想最干净的方法就是更改scope变量。。我真的很喜欢你的例子(就我个人而言,我更喜欢保持作用域和变量名的一致性,这就是为什么我走这条路线),但它真的只在Chrome中受支持?哦,对不起。。。我把ES5
bind
与Object混淆了。请注意ES7提案中的绑定。这只是一个快速浏览,感谢您确认:P我想您可能指的是
fn.apply(内容、参数)
行,因为我的mdn到处竖起大拇指:()。是的,我可以做到,而且可能会做到。主要是跨范围的一致性。谢谢你。