【问题标题】:Angular 2: Component Interaction, optional input parametersAngular 2:组件交互,可选输入参数
【发布时间】:2017-02-04 15:18:51
【问题描述】:

我有一个实现,其中父组件希望通过使用子组件可用的@Input 参数将某些数据传递给子组件。但是,此数据传输是可选的,父级可能会也可能不会根据要求传递它。组件中是否可以有可选的输入参数。我在下面描述了一个场景:

 <parent>
    <child [showName]="true"></child> //passing parameter
    <child></child> //not willing to passing any parameter
</parent>



//child component definition
@Component {
    selector:'app-child',
    template:`<h1>Hi Children!</h1>
          <span *ngIf="showName">Alex!</span>`
}


export class child {

    @Input showName: boolean;

    constructor() { }

}

【问题讨论】:

  • 是的,您可以有可选输入,如果输入已初始化,请检查 ngAfterViewInit 生命周期事件
  • 感谢@galvan,它成功了!

标签: angular angular2-components


【解决方案1】:

您可以使用 ( ? ) 运算符,如下所示

import {Component,Input} from '@angular/core';
@Component({
    selector:'child',
    template:`<h1>Hi Children!</h1>
          <span *ngIf="showName">Alex!</span>`
})


export class ChildComponent {

    @Input() showName?: boolean;

    constructor() { }

}

使用子组件的父组件将是as

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <child [showName]="true"></child>
      <child ></child>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

LIVE DEMO

【讨论】:

  • 这应该是答案。也适用于默认值@Input() showName?: boolean = true;
  • 我想知道,与普通的 @Input() showName: boolean; 有什么区别吗?然后检查是否不为空?我的意思是 - 有什么区别?
  • @RoyiNamir 最重要的是,我想说,它是一种文档形式。通过放置 ?您是否可以沟通您的组件是否可以处理未定义的输入。另外,我认为它被strictNullChecks编译器选项christianliebel.com/2017/05/…所识别
  • @MatthiasTylkowski 如果您设置了默认值,那么将其设为可选是没有意义的,因为它总是会被设置为某个值。
  • @MatthiasTylkowski 可选意味着 showName 属性可能不存在,但默认设置为 true 意味着它将始终存在,因此将其设为可选没有意义。 (此处的 null 无关紧要,设置为 null 的属性仍然存在。可选仅与已定义或未定义有关。)-此处的可选不是指是否必须传入输入(默认情况下输入是可选的),而是是否属性 showName 必须存在于类中。
【解决方案2】:

默认情况下,输入值是可选的。仅当您的代码尝试访问未实际传递的输入的属性时(因为这些输入是 undefined),您的代码才会失败。

您可以实现 OnChanges 或将输入设为 setter 而不是属性,以便在实际传递值时执行您的代码。

export class child {

    @Input set showName(value: boolean) {
      this._showName = value;
      doSomethingWhenShowNameIsPassed(value);
    }

    constructor() { }
}

【讨论】:

  • 查看@galvan 的评论,这似乎是一个更好的解决方案。
  • 为什么你认为它更好?当父级必须向服务器发出请求,然后才将值传递给子级时,这可能是在调用ngAfterViewInit() 之后的一段时间。 ngAfterViewInit() 可能适用于您的具体情况,但总的来说我不推荐它。
  • 您的意思是,如果我在客户端动态更改值?正如你所解释的,我应该在子指令中调用 setter 方法吗?
  • 你不需要调用setter,但是如果你有&lt;child [showName]="propOnParent"&gt;propOnParent在一些异步调用完成后被初始化,那么Angular会更新showName输入在&lt;child&gt;或如果是 setter,则使用更新后的值调用 setter。
  • 另外,如果您在问题中只关心像 true 这样的静态绑定值,ngOnInit() 是比 ngAfterViewChecked() 更常见的生命周期挂钩。
【解决方案3】:

这里有两个选择。

1) 您可以在子级上使用*ngIf,以防子级在其输入为空时不需要显示。

 <parent>
    <child *ngIf="true" [showName]="true"></child> //passing parameter
    <child></child> //not willing to passing any parameter
</parent>

2) 如果子项在没有任何输入的情况下显示,您可以使用修改后的 setter 来检查输入变量的存在`

在 child.ts 中:

private _optionalObject: any;
@Input()
set optionalObject(optionalObject: any) {
    if(optionalObject) this._optionalObject = optionalObject;
}
get optionalObject() { return this._optionalObject; }

【讨论】:

  • 查看@galvan 的评论,这似乎是一个更好的解决方案。
猜你喜欢
  • 2017-08-26
  • 1970-01-01
  • 2016-10-12
  • 2020-09-15
  • 2019-05-12
  • 2016-07-19
  • 1970-01-01
  • 2018-09-23
  • 2016-03-16
相关资源
最近更新 更多