将数据从 Angular 守卫传递到组件失败
Passing data from Angular guard to component fails
我从守卫那里收到一组数据,这组数据包含预期的数据。我的问题是将数据集传递给我的组件。
这是我的代码:
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”的输入 属性,用新的 User 实例对其进行初始化
- 在构造函数之后,Input 属性逐个接收使用 属性 绑定语法给出的值。这些属性中的每一个都将触发 ngOnChanges 生命周期的事件。在您的情况下,ngOnChanges 将在您的构造函数之后和 ngOnInit 之前触发一次,因为只有一个 Input decorated 属性
- 当 属性 绑定、事件绑定和放置在组件选择器上的指令得到正确管理时,将执行 ngOnInit 挂钩。在这里,您尝试在“用户”输入 属性.
上设置“姓名”和“年龄”属性
根据您发布的那段代码,这是我的猜测:您在组件中初始化了“用户”属性,为其提供了一个新的 User 实例,但是当 Angular 尝试在构造函数执行后立即从外部对其进行初始化。
换句话说,如果您有这样的选择器:
<app-user-editor></app-user-editor>
您必须确保在父组件中应用了针对“用户”属性 的 属性 绑定,如下所示:
<app-user-editor [user]="aUserInstance"></app-user-editor>
此外,请确保提供给用户的值 属性 是 UserEditorComponent 中预期的 User 实例:如果您发送未初始化的值(未定义),它将触发您遇到的错误在您的控制台日志中看到。
如果可以的话,您在 UserEditorComponent 中执行的初始化是无用的,因为它会被传入值覆盖。请改用此语法:
@Input() user!: User;
告诉用户 属性 是一个 User 实例,并且它将在构造函数之后以某种方式正确初始化(为此需要 TypeScript 中的 ! 字符)就足够了。
编辑
检查 github 上的代码,我看到解析器返回的对象被包装到“用户”键中,因此解析器订阅上的 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;
});
}
当 Resolver returns 某物时,它使用路由器配置中使用的相同密钥将数据包装在一个对象中(以下是用户的 repo Router):
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
}
},
],
}
];
如果你想查看所做的所有改进,你可以转到我在用户的 repo 上提出的 pull request https://github.com/Christoph1972/routing-guard-test/pull/1
我从守卫那里收到一组数据,这组数据包含预期的数据。我的问题是将数据集传递给我的组件。
这是我的代码:
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”的输入 属性,用新的 User 实例对其进行初始化
- 在构造函数之后,Input 属性逐个接收使用 属性 绑定语法给出的值。这些属性中的每一个都将触发 ngOnChanges 生命周期的事件。在您的情况下,ngOnChanges 将在您的构造函数之后和 ngOnInit 之前触发一次,因为只有一个 Input decorated 属性
- 当 属性 绑定、事件绑定和放置在组件选择器上的指令得到正确管理时,将执行 ngOnInit 挂钩。在这里,您尝试在“用户”输入 属性. 上设置“姓名”和“年龄”属性
根据您发布的那段代码,这是我的猜测:您在组件中初始化了“用户”属性,为其提供了一个新的 User 实例,但是当 Angular 尝试在构造函数执行后立即从外部对其进行初始化。
换句话说,如果您有这样的选择器:
<app-user-editor></app-user-editor>
您必须确保在父组件中应用了针对“用户”属性 的 属性 绑定,如下所示:
<app-user-editor [user]="aUserInstance"></app-user-editor>
此外,请确保提供给用户的值 属性 是 UserEditorComponent 中预期的 User 实例:如果您发送未初始化的值(未定义),它将触发您遇到的错误在您的控制台日志中看到。
如果可以的话,您在 UserEditorComponent 中执行的初始化是无用的,因为它会被传入值覆盖。请改用此语法:
@Input() user!: User;
告诉用户 属性 是一个 User 实例,并且它将在构造函数之后以某种方式正确初始化(为此需要 TypeScript 中的 ! 字符)就足够了。
编辑 检查 github 上的代码,我看到解析器返回的对象被包装到“用户”键中,因此解析器订阅上的 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;
});
}
当 Resolver returns 某物时,它使用路由器配置中使用的相同密钥将数据包装在一个对象中(以下是用户的 repo Router):
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
}
},
],
}
];
如果你想查看所做的所有改进,你可以转到我在用户的 repo 上提出的 pull request https://github.com/Christoph1972/routing-guard-test/pull/1