问题:
1.在父组件模板中,使用ngIf来控制子组件显示时,子组件的离场动画,不生效!!
2.神坑!!!
import {Observable} from ‘rxjs’会报错!!!
必须像下面一样才行
import {Observable} from ‘rxjs/Observable’;
不知道为什么!
3.sails waterline方法都是异步的。
如 User.find()、User.create();
我希望注册时,可以先寻找该注册信息是否已存在。于是写了如下代码:
User.find(name,function userFound(err,user){
if(err) return res.send(500,{error:err});
if(user) {
return res.send({error:"昵称已存在"},500);
}
})
User.create(params,function userCreated(err,createdUser){
if(err) return res.send(err,500);
});
运行后,报错Can’t set headers after they are sent
查了下资料,发现waterline方法为异步。也就是说在执行find时,同时也会执行create。
而两个方法同时return了一个response。
当find优先执行回调,返回res后,create也执行了回调,返回了res。
解决方法很简单:
User.find(name,function userFound(err,user){
if(err) return res.send(500,{error:err});
if(user) {
return res.send({error:"昵称已存在"},500);
}
User.create(params,function userCreated(err,createdUser){
if(err) return res.send(err,500);
});
})
在find的回调函数中,执行create方法。
4.
问题:我的头部数据初始化是在ngOnInit,但是发现路由跳转到登陆页面后,并登陆成功返回首页路由时,header的component里的ngOnInit没有执行。
原因:我的app.component.html代码
<my-header></my-header>
<router-outlet></router-outlet>
开始,我在header.component.html里代码如下:
<a routerLink="/login">登陆</a>
<router-outlet></router-outlet>
而路由设置为跳转到某个component。
此时,my-header不包括在router-outlet里面。
导致每次的路由跳转,头部没有改变,一直是渲染后的状态。所以当跳转回主页时,header component的ngOnInit不会再触发。
另外,子组件里的router-outlet不起作用,默认渲染在父组件的router-out
解决方法:my-header包裹在router-outlet的html中即可。
更新最佳解决方法
angular在处理同一页面内跳转时,不会重新创建组件中的实例。所以header组件中的构造函数和ngOnInit方法都不会再次调用。
需用ActivatedRoute服务来提供Observable对象,对路由链接的更新进行订阅,并且在组件销毁时应取消订阅,避免内存泄漏。
ngOnInit() {
this.sub=this.activatedRoute.url.subscribe(url=>{
this.getUser();
})
}
5.use canActivate with Observable
在使用canActivate对路由进行安全守卫时,如何获取当前登陆的user权限是个问题。
以下是遇到的坑:
(1)一开始在获取当前用户信息的service中,新增一个变量isAuth。在component的subscribe中,成功时,设置service中的isAuth变量。然而,canActivate中获取到的isAuth只在一开始进入路由时有效,刷新后则无效!这时候UserService实例为新实例,原来的isAuth还原。
(2)
dataStringSource=new Subject<Number>();
isAuth=this.dataStringSource.asObservable();
在UserService中,定义以上变量。
并且新建方法
setAuth(data:Number) {
this.dataStringSource.next(data);
}
在初始化获取user信息时,并且调用这个方法。
然而,由于rxjs中,next方法需在订阅之后(也就是subscribe之后),而canActivated的构造函数总是在点击编辑时才执行。此时,subscribe在next之后。于是subscribe失败。需进入到编辑页面时,才会成功。
(3)于是我尝试将该订阅放置canactivated方法中。
return this.userService.isAuth.subscribe({
next:data=> {
this.isAuth=data;
console.log("data",data);
}
})
但由于canActivated接口要求返回boolean类型(可以为Obversable)。所以用订阅方法时,虽然在成功回调中,我return了boolean值,但由于整体返回的总是一个Obversable,而非Obversable,所以报错。
(4)我尝试在user.service中写入以下代码:
isPass:AsyncSubject<any>= new AsyncSubject();
authenticated(user?) {
console.log("user",user);
if(user) {
console.log("user---1");
if(user.type) {
console.log("user---2");
this.isPass.next(true);
}else {
this.isPass.next(false);
}
}else {
this.get().subscribe(
data=>{
console.log("authentic",data.type);
if(data.type) {
this.isPass.next(true);
}else {
this.isPass.next(false);
}
this.isPass.complete();
},
error=>{
this.isPass.next(false);
this.isPass.complete();
}
)
}
}
在CanActivated.service中,代码如下:
return this.userService.isPass
.do(
isPass=>{console.log("ispass",isPass);
if(!isPass)this.router.navigate(['/login']);},
error=>console.log(error));
然而每次canActivated中的执行,该订阅也就是do总是获取到最初的next值。后续的next值皆无效。
(5)最后 我找到了解决方法。
UserService
isPass:AsyncSubject<any>= new AsyncSubject();
CanActivated.service
return this.userService.get().map(user=>{
if(user.type) {
return true;
}
return false;
}).catch(()=>{
this.router.navigate(['/login']);
return Observable.of(false);
})