Angular点击CheckLogin按钮路由报错:cannot read property 'navigate' of undefined
我来帮你搞定这个错误!你遇到的cannot read property 'navigate' of undefined问题,本质原因是jQuery Ajax的success回调函数里的this指向不对——它指向的是回调函数自身的上下文,而不是你的GuessComponent组件实例,所以自然找不到router对象。
下面给你几种可行的修复方案,按推荐程度排序:
方案1:使用箭头函数(最简洁)
ES6的箭头函数不会创建自己的this,而是继承外部作用域的this,也就是你的组件实例。直接把success回调改成箭头函数就行:
CheckLogin(name,pass) { $.ajax({ headers:{ "Accept":"application/json", "Content-type":"application/x-www-form-urlencoded" }, url:"http://199.188.207.196:5555/user/login/", method:"post", data:{"email":name,"password":pass}, // 把普通函数改成箭头函数 success:(response) => { if(response.success == true){ console.log("ok"); this.router.navigate(['/main']); // 现在this指向组件实例,router能正常访问 } else{ console.log("backend"); } } }); }
方案2:提前保存组件的this到变量
在Ajax调用前,把组件的this存到一个变量(比如that),然后在回调里用这个变量代替this:
CheckLogin(name,pass) { const that = this; // 保存组件的this引用 $.ajax({ headers:{ "Accept":"application/json", "Content-type":"application/x-www-form-urlencoded" }, url:"http://199.188.207.196:5555/user/login/", method:"post", data:{"email":name,"password":pass}, success:function(response){ if(response.success == true){ console.log("ok"); that.router.navigate(['/main']); // 使用that访问组件的router } else{ console.log("backend"); } } }); }
方案3:用bind()绑定上下文
给success回调函数绑定组件的this,强制回调里的this指向组件实例:
CheckLogin(name,pass) { $.ajax({ headers:{ "Accept":"application/json", "Content-type":"application/x-www-form-urlencoded" }, url:"http://199.188.207.196:5555/user/login/", method:"post", data:{"email":name,"password":pass}, success:function(response){ if(response.success == true){ console.log("ok"); this.router.navigate(['/main']); } else{ console.log("backend"); } }.bind(this) // 绑定组件的this到回调函数 }); }
额外建议:改用Angular官方的HttpClient
其实在Angular项目里,不推荐用jQuery的Ajax,Angular自带的HttpClient更适配框架生态,而且不会有上下文问题。给你一个示例:
首先在组件里导入HttpClient和相关类:
import { Component, OnInit} from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; // 替换旧的Http import { Router} from '@angular/router'; @Component({ selector: 'app-guess', templateUrl: './guess.component.html', styleUrls: ['./guess.component.css'] }) export class GuessComponent implements OnInit { // 注入HttpClient constructor(private router: Router, private http: HttpClient) {} ngOnInit() { } CheckLogin(name,pass) { const headers = new HttpHeaders({ "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded" }); // 因为Content-Type是x-www-form-urlencoded,需要把数据转成url编码格式 const body = new URLSearchParams(); body.set('email', name); body.set('password', pass); this.http.post("http://199.188.207.196:5555/user/login/", body.toString(), { headers }) .subscribe( response => { if(response['success'] === true){ console.log("ok"); this.router.navigate(['/main']); } else { console.log("backend"); } }, error => { console.error('登录请求出错:', error); } ); } }
别忘了在你的AppModule里导入HttpClientModule:
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // ...其他模块 HttpClientModule ] }) export class AppModule { }
这样不仅能解决路由问题,还能更好地和Angular的RxJS、变更检测等机制配合。
内容的提问来源于stack exchange,提问作者kappo
相关产品推荐
相关产品推荐

