Angular 2 / TypeScript:@ Input / @ output或input / output?

时间:2016-12-25 04:00:57

标签: angular typescript

在Udemy上做一门课程时,我们一直允许组件使用组件类中的@Input()装饰器传递数据。

在阅读ngBook-2时,我发现在input装饰器中使用@Component属性还有另一种方法。

关于SO的{p> THIS类似问题,有人回答:

  

使用输入的一个优点是类的用户只需要查看传递给@Component装饰器的配置对象来查找输入(和输出)属性。

并查看documentation说明:

  

无论您使用输入/输出还是@ Input / @输出结果都是相同的,因此选择使用哪一个主要是风格决定。

实际上,最有用的信息主要是相互矛盾的,具体取决于你的目标。

内部@Component

 @Component({
  selector: 'product-image',
  inputs: ['product'],
  template: `
  <img class="product-image" [src]="product.imageUrl">
})

class ProductImage {
  product: Product;
}

内部课程

@Component({
  selector: 'product-image',
  template: `
  <img class="product-image" [src]="product.imageUrl">
})

class ProductImage {
  @Input() product: Product;
}

我想知道的事情

  • 更多的是“最佳实践”用法?
  • 你什么时候使用一个?
  • 是否有任何差异?

2 个答案:

答案 0 :(得分:7)

Angular 2风格指南

根据官方Angular 2 style guideSTYLE 05-12

  

使用@Input@Output代替@Directive@Component装饰器的输入和输出属性

好处是(来自指南):

  • 识别类中的哪些属性是输入或输出更容易,更易读。
  • 如果您需要重命名与@Input@Output相关联的媒体资源或事件名称,则可以将其修改为一个地方。
  • 附加到指令的元数据声明更短,因此更具可读性。
  • 将装饰器放在同一行上可以缩短代码,并且仍然可以轻松地将属性标识为输入或输出。

我个人使用过这种风格,非常感谢它帮助保留代码DRY

答案 1 :(得分:1)

我知道你可以用装饰器做的一件很酷的事情,但是如果用另一种方法可以做到的话,那就是变量别名:

export class MyComponent {

 @Output('select') $onSelect = new EventEmitter<any>(); // this is aliased

 @Output() finish  = new EventEmitter<any>(); // not aliased

 sendUp(){
    this.$onSelect.emit('selected'); 

    this.finish.emit('done');
 }
}

然后从外面:

 <my-component (select)="doSomething($event)"></my-component>

另一个是设置默认值,你可以用两种方式设置默认值,但装饰器看起来更方便,代码更少。

@Component({ 
  selector:'my-component'
})
export class MyComponent {
  @Input() id = 'default-id';     

  ngOnInit(){

    console.log('id is : ',this.id); // will output default-id if you don't pass anything when using the component
  }
}

所以在这种情况下,如果消费者没有将id作为输入传递,你仍然有 default-id ;

 <my-component></my-component>;

如果您想使用输入数组执行此操作,则执行以下操作:

@Component({ 
  selector:'my-component',
  inputs:['id']
})
export class MyComponent {
  private id = 'default-id';     

  ngOnInit(){

    console.log('id is : ',this.id); // will output default-id if you don't pass anything when using the component
  }
}

结果是一样的,但是如果你注意到,在这种情况下你必须将 id 放在 inputs array 中并在类中定义它。

编辑:

显然,也可以使用输出[]进行别名,如下:

@Component({
  selector: 'my-component',
  template: `
   <button (click)="sendUp()">Send up</button>
  `,
  outputs: ['$onSelect: select']
})
export class ChildComponent {
  $onSelect = new EventEmitter<any>(); // this is aliased

  sendUp() {
    this.$onSelect.emit('selected');
  }
}

但是你必须在两个地方定义它,在数组中和类中的一个,所以我仍然更喜欢装饰器。