问题描述
我从守卫那里收到一组数据,该组数据包含预期的数据。我的问题是将数据集传递给我的组件。
这是我的代码:
export class UserEditorComponent implements OnInit,OnDestroy {
@input()
user = new User();
constructor(private activatedRoute: ActivatedRoute) {}
private subscription: Subscription | null = null;
ngOnInit(): void {
this.subscription = this.activatedRoute.data.subscribe(x => {
console.log("Incoming data ",x); //the incoming contains the expected data (name & age)
console.log("Class Field user",this.user); //the field "user" is initialized with default values
this.user.Name = x.Name;
this.user.Age = x.Age;
console.log("Check user ",this.user); //user is undefined
});
}
}
这里有什么问题?我期待你的回答! :-)
亲切的问候 克里斯托夫
解决方法
答案依赖于 Angular 的组件生命周期。让我们检查一下您的组件的生命周期会发生什么:
- 您定义一个名为“user”的 Input 属性,并使用新的 User 实例对其进行初始化
- 在构造函数之后,Input 属性会一一接收通过属性绑定语法给出的值。这些属性中的每一个都会触发 ngOnChanges 生命周期的事件。在您的情况下,ngOnChanges 将在您的构造函数之后和 ngOnInit 之前触发一次,因为只有一个 Input 装饰属性
- 当属性绑定、事件绑定和放置在组件选择器上的指令被正确管理后,ngOnInit 钩子就会被执行。在这里,您尝试在“user”输入属性上设置“name”和“age”属性。
这是我的猜测,依赖于您发布的那段代码:您在组件中初始化“user”属性,为其提供一个新的 User 实例,但是当 Angular 尝试从外部初始化它时,您丢失了它,立即在构造函数执行之后。
换句话说,如果你有一个这样的选择器:
<app-user-editor></app-user-editor>
您必须确保在父组件中应用了针对“用户”属性的属性绑定,如下所示:
<app-user-editor [user]="aUserInstance"></app-user-editor>
此外,请确保提供给 user 属性的值是 UserEditorComponent 中预期的 User 实例:如果您发送未初始化的值(未定义),它将触发您在控制台日志中看到的错误。
如果可以的话,您在 UserEditorComponent 中执行的初始化是无用的,因为它将被传入的值覆盖。请改用以下语法:
@Input() user!: User;
告诉 user 属性是一个 User 实例,并且它会在构造函数之后以某种方式正确初始化(为此需要 TypeScript 中的 ! 字符)就足够了。
编辑 查看github上的代码,发现Resolver返回的对象被包裹在了“user”键中,所以解析器的订阅上的x参数被访问不当:
this.subscribtion = this.activatedRoute.data.subscribe(x => {
this.user.Name = x..user.Name; // Was this.user.Name = x.Name
this.user.Age = x.user.Age; // Was this.user.Age = x.Age;
});
}
当解析器返回某些内容时,它会将数据包装在一个对象中,该对象与路由器配置中使用的键相同(以下是用户的存储库路由器):
const routes: Routes = [
{
path: 'user',component: UserComponent,children: [
{
path: ':name',component: UserEditorComponent,resolve: {
// Data returned by the UserGuard Resolver is placed into the "user" key
// so,subscribing to the resolver Observable,will return an object with
// user: {Age: number,Name: string}
user: UserGuard
}
},],}
];
如果您想查看所做的所有改进,可以转到我在用户的存储库中提出的拉取请求 https://github.com/Christoph1972/routing-guard-test/pull/1