【问题标题】:Update view on ngOnChanges from @Input in Angular从 Angular 中的 @Input 更新 ngOnChanges 视图
【发布时间】:2019-08-24 23:50:06
【问题描述】:

我在 Person 类型的子组件中有一个 @Input 属性,并且我正在通过属性从父组件传递对象

完整的工作代码在StackBlitz 中提供

我探索了以下问题,我明白了他们在答案中所说的内容,但我根据答案尝试了 Object.assign 和其他东西,但它无法在 View 中加载数据。

如何通过@Input 传递对象,一旦对象到达子组件并需要在视图中更新,我如何进行一些操作?

示例代码:

应用组件

import { Component } from '@angular/core';

import { Person } from './models/person'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  person: Person = {
    firstName: 'Emma',
    lastName: 'Watson'
  };
}

应用组件 HTML

<user [user-profile]="person"></user>

用户组件

import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
import { Person } from '../models/person';

@Component({
  selector: 'user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit, OnChanges {

  @Input('user-profile') profile: Person;

  person: Person;

  constructor() {}

  ngOnInit() { 
    this.person = {
      firstName: '',
      lastName: ''
    }
  }

  ngOnChanges(changes:SimpleChanges): void { 
    if(typeof this.profile !== 'undefined' 
      && typeof this.profile.firstName !== 'undefined' 
      && typeof this.profile.lastName !== 'undefined') {
        this.person.firstName = this.profile.firstName;
        this.person.lastName = this.profile.lastName;
    }
  }

}

用户组件 HTML

Full Name: {{person.firstName}} {{person.lastName}}

@Input 收到对象后,我需要进行一些操作,并需要在 UI 中更新它。我知道该对象作为参考传递,但在这里我尝试使用 Object.assign 并使用 undefined 分配属性,然后适当的对象没有任何工作。

【问题讨论】:

    标签: javascript angular javascript-objects angular-components ngonchanges


    【解决方案1】:

    ngOnInit() 中删除person 的分配,ngOnInit 在ngOnChanges 之后运行,因此您将值恢复为空

    export class UserComponent implements OnInit, OnChanges {
    
      @Input('user-profile') profile: Person;
    
      person: Person = { firstName: '', lastName: '' };  // initialize it here
    
      constructor() {}
    
      ngOnInit() { 
        // this.person = {
        //   firstName: '',
        //   lastName: ''
        // }
      }
    
      ngOnChanges(changes:SimpleChanges): void { 
    
    
    
        if(typeof this.profile !== 'undefined' 
          && typeof this.profile.firstName !== 'undefined' 
          && typeof this.profile.lastName !== 'undefined') {
            console.log(this.profile)
            this.person.firstName = this.profile.firstName;
            this.person.lastName = this.profile.lastName;
            console.log(this.person)
        }
      }
    
    }
    

    https://stackblitz.com/edit/angular-input-ng-onchange-qiyghn?file=src%2Fapp%2Fuser%2Fuser.component.ts

    【讨论】:

      【解决方案2】:

      这是因为ngOnInitngOnChanges 之后运行。所以你首先设置它,然后立即在你的ngOnInit 中重置它。

      请参阅 here 一个工作示例。

      基本上把你的组件 person 属性改成这样:

      person: Person = {
        firstName: '',
        lastName: ''
      };
      

      并删除ngOnInit

      您也可以在配置文件输入上使用设置器,这样您就不需要ngOnChanges

      @Input('user-profile') set profile(person: Person) {
        this.person.firstName = profile && profile.firstName || '';
        this.person.lastName = profile && profile.lastName || '';
      }
      
      person: Person = {
        firstName: '',
        lastName: ''
      };
      

      【讨论】:

      • 我应该在构造函数中做初始赋值吗?
      • @B.Balamanigandan 我个人认为在属性本身上这样做更整洁,但这并不重要,功能将是相同的。在 Angular 中,通常将构造函数保持为空,并将其用于依赖注入
      • 别误会我。我标记基于FIFO。我首先投票赞成你回答。
      • @B.Balamanigandan 不用担心 :) 我理解你的推理。我实际上确实先回答了,但在一分钟内进行了编辑,这使编辑与原始答案合并,并将时间戳更新为另一个答案之后。但是xyz更值得,他需要积分!
      猜你喜欢
      • 2017-09-30
      • 2021-10-03
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 2022-07-01
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      相关资源
      最近更新 更多