将数据从 Angular 防护传递到组件失败

问题描述

我从守卫那里收到一组数据,该组数据包含预期的数据。我的问题是将数据集传递给我的组件。

这是我的代码

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 的组件生命周期。让我们检查一下您的组件的生命周期会发生什么:

  1. 您定义一个名为“user”的 Input 属性,并使用新的 User 实例对其进行初始化
  2. 在构造函数之后,Input 属性会一一接收通过属性绑定语法给出的值。这些属性中的每一个都会触发 ngOnChanges 生命周期的事件。在您的情况下,ngOnChanges 将在您的构造函数之后和 ngOnInit 之前触发一次,因为只有一个 Input 装饰属性
  3. 当属性绑定、事件绑定和放置在组件选择器上的指令被正确管理后,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