【问题标题】:Object not being passed with @Input decorator Angular2对象没有通过@Input 装饰器 Angular2 传递
【发布时间】:2018-02-07 14:04:06
【问题描述】:

从订阅获取数据时,我的数据没有绑定到我的本地变量。

我有两个组件和一个服务。父组件从服务调用一个方法来做一个 http get,get 包括一个我需要绑定的用户对象。 但是,当 console.logging 订阅之外的对象时,它看起来是未定义的。

这是我的代码:

父组件:

selectedUser : User;
  onUserRowSelect(event): void {
    this.router.navigate(['../childComponent'], { relativeTo: this.route });

    this.formService.getUser(event.data.USER_ID).subscribe(result => {
      console.log(result); // <-- Object is logged properly.
      this.selectedUser = result; // Assigning the local @Input variable to the result
    });
  }

子组件:

  @Input() selectedUser : User;

      ngOnInit() {
        console.log(this.selectedUser); // Returns undefined.
      }

使用 Http 的服务:

getUser(id: number): Observable<User> {
    const _url = 'myURL/getuser/' + id;
    const headers = new Headers();
    headers.append('X-User', sessionStorage.getItem('username'));
    headers.append('X-Token', sessionStorage.getItem('token'));
    headers.append('X-AccessTime', sessionStorage.getItem('AccessTime'));
    headers.append('Content-Type', 'application/json');
    const options = new RequestOptions({ headers: headers });

    return this.http.get(_url, options)
        .map(response => {
            const responseAsObject = response.json();
            this.myUser = responseAsObject;
            return responseAsObject;
        });
}

所以我的问题在于即使在将@input 装饰器添加到变量之后,子组件中的 selectedUser 仍出现未定义。

父 HTML:

    <div>
    <div class="row-md-6">
        <nb-card title="List of Users">
            <ng2-smart-table [settings]="settings" [source]="source" (userRowSelect)="onUserRowSelect($event)"></ng2-smart-table>
        </nb-card>
    </div>
</div>

子 HTML:

<div id="top">
<nb-card>
    <nb-card-header>Update User</nb-card-header>
    <nb-card-body header="Update User">
        <div class='row'>
            <div class='col-md-6'>
                <form [formGroup]="complexForm" (ngSubmit)="submitForm(complexForm.value)">
                    <div class="form-group" [ngClass]="{'has-error':!complexForm.controls['username'].valid}">
                        <label>Username</label>
                        <input [(ngModel)]="username" class="form-control" id="username" type="text" [formControl]="complexForm.controls['username']">
                    </div>
                    <div class="form-group" [ngClass]="{'has-error':!complexForm.controls['group_id'].valid}">
                        <label>Group ID</label>
                        <div class="row" *ngIf="roles.length">
                            <div class="col-md-4">
                                <select [(ngModel)]="selectedGroup" name="group_id" (change)="onChange($event)" class="form-control" [formControl]="complexForm.controls['group_id']"
                                    data-width='200px'>
                                    <option [ngValue]="role.GROUP_ID" *ngFor="let role of roles">
                                        {{role.NAME}}
                                    </option>
                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>First Name</label>
                        <input [(ngModel)]="fname" class="form-control" type="text" [formControl]="complexForm.controls['fname']">
                    </div>
                    <div class="form-group">
                        <label>User ID</label>
                        <input [(ngModel)]="ID" class="form-control" type="text" [formControl]="complexForm.controls['USER_ID']">
                    </div>
                    <div class="form-group">
                        <label>Last Name</label>
                        <input [(ngModel)]="lname" class="form-control" type="text" [formControl]="complexForm.controls['lname']">
                    </div>
                    <div class="form-group">
                        <label>Organization</label>
                        <input [(ngModel)]="organization" class="form-control" type="text" [formControl]="complexForm.controls['organization']">
                    </div>
                    <div class="form-group">
                        <label>Phone</label>
                        <input [(ngModel)]="phone" class="form-control" type="text" [formControl]="complexForm.controls['phone']">
                    </div>
                    <div class="form-group">
                        <label>Creation Date</label>
                        <input [(ngModel)]="creationDate" class="form-control" type="text" [formControl]="complexForm.controls['creation_date']">
                    </div>
                    <div class="form-group">
                        <label>Last Login</label>
                        <input [(ngModel)]="lastLogin" class="form-control" type="text" [formControl]="complexForm.controls['last_login']">
                    </div>
                    <div class="form-group" [ngClass]="{'has-error':!complexForm.controls['status'].valid}">
                        <label>Status</label>
                        <div class="row" *ngIf="statuses.length">
                            <div class="col-md-6">
                                <select [(ngModel)]="selectedStatus" name="stasus" (change)="onChange($event)" class="form-control" [formControl]="complexForm.controls['status']"
                                    data-width='500px'>
                                    <option [ngValue]="status.STATUS" *ngFor="let status of statuses">
                                        {{status.STATUS_DESC}}
                                    </option>
                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>Logged In</label>
                        <input [(ngModel)]="loggedIn" class="form-control" type="text" [formControl]="complexForm.controls['logged_in']">
                    </div>
                    <div class="form-group">
                        <label>Password Bad Tries</label>
                        <input [(ngModel)]="pwdBadTries" class="form-control" type="text" [formControl]="complexForm.controls['pwd_badtries']">
                    </div>
                    <div class="form-group">
                        <label>Title</label>
                        <input [(ngModel)]="title" class="form-control" type="text" [formControl]="complexForm.controls['title']">
                    </div>
                    <div class="form-group">
                        <label>Email</label>
                        <input [(ngModel)]="email" class="form-control" type="text" [formControl]="complexForm.controls['email']">
                    </div>
                    <div class="form-group">
                        <label>User Expiry in Days</label>
                        <input [(ngModel)]="userExpiryInDays" class="form-control" type="text" [formControl]="complexForm.controls['user_expiry_in_days']">
                    </div>
                    <div class="form-group" [ngClass]="{'has-error':!complexForm.controls['restricted_ip'].valid}">
                        <label>Restricted IP</label>
                        <input [(ngModel)]="restrictedIp" class="form-control" type="text" [formControl]="complexForm.controls['restricted_ip']">
                        <div *ngIf="complexForm.controls['restricted_ip'].hasError('pattern') && complexForm.controls['restricted_ip'].touched" class="alert alert-danger">Not a valid IP Address.</div>
                    </div>
                    <div class="form-group">
                        <label>Password Expiry Date</label>
                        <input [(ngModel)]="pwdExpdate" class="form-control" type="text" [formControl]="complexForm.controls['pwd_expdate']">
                    </div>
                    <div class="form-group">
                        <button type="submit" value="update" [disabled]="!complexForm.valid" class="btn btn-success">Update User</button>
                    </div>
                </form>
                <div>
                    <button type="submit" value="delete" class="btn btn-success" (click)="confirmDelete()">Delete User</button>
                </div>
                <br/>
                <div>
                    <button type="submit" value="delete" class="btn btn-success" (click)="getNewPassword()">Set Password</button>
                </div>
            </div>
        </div>
    </nb-card-body>
</nb-card>

【问题讨论】:

  • 使用ngOnChanges 而不是ngOnInit
  • ngOnChanges 从未被调用,它没有登录控制台。
  • ngOnInit 之前必须调用第一个ngOnChanges。见这里:angular.io/guide/lifecycle-hooks 你用过implements OnChanges 吗?尝试console.log 进行其他检查(例如console.log(42);)。
  • 是的,我确实添加了正确的工具,它在你的意思是放在代码中的位置有关系吗?
  • 没有。你试过ngOnChanges() { console.log(42); }吗?

标签: angular


【解决方案1】:

确实是老问题,但这里的答案是构造函数上不存在输入,但最终会存在。使用 ngOnInit 查看输入。

class ChildComponent implements OnInit {
  ngOnInit() {
    console.log(changes.selectedUser);
  }
  ...
}

【讨论】:

    【解决方案2】:

    您的 onInit 子进程执行得太快了。添加一个 ngOnChanges 方法并记录所有更改。您应该会看到,当它稍后在父级中可用时,它也会在子级上得到更新。

    class ChildComponent implements OnChanges {
      ngOnChanges(changes: SimpleChanges) {
        console.log(changes.selectedUser);
      }
      ...
    }
    

    请注意,您不需要 ngOnChanges 来获取它们。仅当您想明确做出反应时。在组件可用之前,您可以简单地准备组件在没有 selectedUser 的情况下工作(或使用 ngIf 等隐藏它)。

    【讨论】:

    • 奇怪,ngOnChanges 从未被调用过。我无法在其中进行控制台登录。
    • 您能否发布整个子组件(在错误消失之前,一一删除任何受限或不必要的代码)?奇怪的是它不会触发 onChanges。
    • 只有构造函数应该在数据存在之前触发。登录 ngOnInit 应该没问题
    • @mast3rd3mon 证明你错了:stackblitz.com/edit/angular-init-changes?file=app/… 如果初始 selectedUser 是同步设置的,那将是真的。但他正在为用户调用后端。
    • 但这不是证据,那是在沙箱中运行,要正确测试,您需要制作一个 Angular 应用程序,在测试时,它能够获取@Input() 中传递的数据在 ngOnInit
    猜你喜欢
    • 1970-01-01
    • 2021-02-11
    • 2015-12-13
    • 1970-01-01
    • 2016-06-18
    • 2014-10-02
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多