Angular-@Input和@Output与可注入服务

时间:2018-06-25 16:07:32

标签: angular typescript design-patterns dependency-injection

我要问自己,上级/下级组件中的@Input / @Output和使用使用仅通过依赖关系注入实例化的服务{{1} }}。或者,除了“输入/输出”只能在parent- / child-comp中使用之外,还有其他区别。

以下示例可提供更好的可视化效果:

使用@Input:

@Injectable()

ChildComponent:

<parent-comp>
   <child-comp [inputFromParent]="valueFromParent"></child-comp>
</parent-comp>

具有依赖注入

@Component({
  selector: 'child-comp',
  template: ...
})
export class ChildComponent {
  @Input() public inputFromParent: string;
}

现在,我们可以在父组件中设置值。并通过依赖注入获得子代的价值。 ChildComponent:

@Injectable()
export class Service {
   private value: string;

public get value(): string {
   return value;
}

public set value(input): void {
   value = input;
}

}

尽管第一种方法看起来更简单,但我认识到通过父子组件使用了3-4个属性carriyng。与@Component({ selector: 'child-comp', template: ... }) export class ChildComponent { private value: string; constructor(private service: Service) { this.value = this.service.getValue; } } / @Input配合使用时,棉塞非常混乱且笨拙。

1 个答案:

答案 0 :(得分:6)

这不是一个具有明确答案的问题,但是...

@Input@Output在父母与子女之间的交流仅仅是父母与子女之间的交流时很有用。拥有一个仅维护两个组件的单例数据的服务就没有任何意义(或者深嵌套的祖父母->父->子组件)。

如果您的父母需要对孩子的变化做出反应,它们也很有用。例如,单击子组件中的一个按钮,该按钮在父组件中调用一个函数:

<my-child-component (myOutputEmitter)="reactToChildChange($event)"></my-child-component>

在父级中:

reactToChildChange(data: any) {
  // do something with data
}

如果您发现自己将许多@Input属性传递给孩子,并且想要整理一个模板,则可以为输入定义一个接口,然后将其传递。例如

export interface MyChildProperties {
   property?: any;
   anotherProperty?: any;
   andAnotherProperty?: any;
}

然后,您可以将定义传递给您的孩子,该定义由父级设置:

childProperties: MyChildProperties = {
    property: 'foo',
    anotherProperty: 'bar',
    andAnotherProperty: 'zoob'
}

那么您的子组件可能具有:

@Input properties: MyChildProperties;

您的模板变为:

<my-child-component [properties]="childProperties"></my-child-component>

您的孩子可以从properties.propertyproperties.anotherProperty等访问这些属性。

干净,整洁,您的数据现在包含在需要通信的那些组件中。

但是,应该在一个以上组件需要访问整个应用程序中的读/写数据的地方使用

服务。例如,考虑一个UserService,其中许多不同的组件需要能够访问当前登录的用户。在这种情况下,服务是明智的,因为它是单例的,因此一旦您设置了登录用户,注入UserService的任何组件都可以访问其数据和功能。

类似地,如果您要使用服务来对更改做出反应,那么您会发现自己使用可观察对象编写服务,以便您的组件可以订阅数据中的更改。如上所述,事件发射器已经使用@Output为您提供了这种模式。

如果它是简单的父级->子级通信,则这是不必要的开销,应该避免。

也就是说,如果您发现自己使用服务来管理全局状态,那么最好使用某种形式的状态管理,例如ngrx