简体   繁体   English

Angular 5 @Input始终在ngOnInit()上未定义

[英]Angular 5 @Input always undefined on ngOnInit()

I'm working on an angular firebase app and I don't know how to solve a problem. 我正在开发一个有角度的Firebase应用程序,但我不知道如何解决问题。 My @Input is always undefined on my ngOnInit() but I have to init something with this Input value. 我的@Input在ngOnInit()上始终是未定义的,但是我必须使用此Input值来初始化一些东西。

ERROR TypeError: Cannot read property 'length' of undefined 错误TypeError:无法读取未定义的属性'length'

I tried to add *ngIf as I saw in similar posts or to initialize my room but nothing is working. 我尝试添加* ngIf,就像在类似的帖子中看到的那样,或者初始化我的房间,但没有任何效果。 Do I have to use a timeout or is there a better way to do that ? 我必须使用超时还是有更好的方法呢?

Here are the details: 详细信息如下:

players component: 玩家组成:

@Input() room: Room;
    players: Player[];
    playersSubscription: Subscription;

    constructor(private playerService: PlayerService, private router: Router) { }

    ngOnInit() {
        this.playersSubscription = this.playerService.playersSubject.subscribe(
            (players: Player[]) => {
                this.players = players;
            }
        );

        this.playerService.getPlayersRoom(this.room.players);

        this.playerService.emitPlayers();

    }

html: 的HTML:

<div *ngIf="room">
    <ul>
        <li *ngFor="let p of room.players">{{p}}</li>
    </ul>
</div>
usernames:
<div *ngIf="players">
    <ul>
        <li *ngFor="let player of players">
            {{player.username}} // This will not works
        </li>
    </ul>
</div>

service: 服务:

    getPlayersRoom(ids: string[]) {

        while (ids.length > 0) {
            var id = ids.splice(0, 1)[0];
            firebase.database().ref('/users/').child(id).once('value', function (snapshot) {
                this.players.push(snapshot.val());
            });
        }
        this.emitPlayers();
}

room: 房间:

room: Room;

constructor(private router: Router,
    private route: ActivatedRoute,
    private roomService: RoomService
) { }

ngOnInit(): void {
    this.room = new Room();
    const id = this.route.snapshot.params['id'];
    this.roomService.getRoom(+id).then(
        (room: Room) => {
            this.room = room;
        }
    );
}

html: 的HTML:

<div *ngIf="room">
        Room n°{{room.id}} + password {{room.password}}
    <h1>PLAYERS room</h1>
    <div *ngFor="let p of room.players">
        {{p}}
    </div>
    Players:
    <app-players *ngIf="room" [room]="room"></app-players>
    end
</div>

Edit: The problem is in ngOnInit (players component): the @Input is undefined at this moment (and then it's doing getPlayersRoom(undefined) ). 编辑:问题出在ngOnInit(玩家组件)中:@Input此时未定义(然后正在执行getPlayersRoom(undefined))。 Any idea someone ? 有人知道吗? Impossible to use a @Input in constructor/ngoninit ? 在构造函数/ ngoninit中不能使用@Input吗? How should I do that then ? 那我该怎么办呢?

Gut response here, but it looks like your roomService.getRoom(+id) is asynchronous, which means depending on what happens when you initialize new Room() , that property may still be undefined by the time your child component is initialized. 在这里得到响应,但看起来您的roomService.getRoom(+id)是异步的,这意味着取决于初始化new Room()时发生的情况,该属性可能在子组件初始化时仍未undefined

Edit: on reflection, maybe you just need to declare your array properties as empty arrays up front: 编辑:反射时,也许您只需要在前面声明数组属性为空数组即可:

players: Player[] = []

I found an alternative solution: 我找到了替代解决方案:

service: 服务:

getPlayersRoom(ids: string[]) {

        for(let i=0;i<ids.length;i++){
            this.getPlayer(ids[i]).then(
                (player: Player) => {
                    if(player){
                       this.players.push(player);
                    }
                }
            );

        }
        this.emitPlayers();
}

component: I implemented OnChanges and then: 组件:我实现了OnChanges,然后:

ngOnChanges(){

        if(Object.keys(this.room).length>0){
            this.playerService.getPlayersRoom(this.room.players);
        }
    }

I don't think that's the best way to do that but at least it's working. 我不认为这是最好的方法,但至少是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM