Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

typescript - Angular - @Input and @Output vs. Injectable Service

I'm asking myself where are the differences between @Input/@Output in parent-/childcomponents and using services which is only once instatiated with dependency Injection@Injectable(). Or are there any differences besides Input/Output can only be used in parent-/child-comp.

Following Example for better visualization:

With @Input:

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

ChildComponent:

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

With dependency Injection

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

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

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

}

Now we can set the value in the parent comp. and get the value in the child comp with dependancy injection. ChildComponent:

@Component({
  selector: 'child-comp',
  template: ...
})
export class ChildComponent {
  private value: string;
  constructor(private service: Service) {
  this.value = this.service.getValue;
}

}

Even though the first approach looks simpler, I recognized using 3-4 properties carriyng through parent-/child comp. with @Input/@Output makes the tamplete very confusing and clunky.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Not exactly a question with a defined answer, but....

@Input and @Output are useful if the communication between a parent and child is just that, between a parent and child. It wouldn't make sense to have a service that maintains singleton data for just 2 components (or however deeply nested grandparent -> parent -> child components are).

They're also useful if your parent needs to react to a change in the child. For example, clicking a button in a child component that calls a function in the parent:

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

And in parent:

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

If you find yourself passing many @Input properties to a child, and want to tidy up a template, then you can define an interface for the input, and pass it instead. e.g.

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

Then you can pass a definition to your child, which is set from the parent:

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

Then your child component may have:

@Input properties: MyChildProperties;

and your template becomes:

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

Your child can access those properties from properties.property, properties.anotherProperty, etc.

Clean, tidy, and your data is now contained to those components that need to communicate.

Services, however, should be used where more than one component needs access to read/write data across your entire application. Consider a UserService for example, where many different components need to be able to access the currently logged in user. In this case, a service is sensible, as its a singleton, so once you have set your logged in user, any components that inject the UserService can access its data and functions.

Similarly, if you were to use a service for reacting to change, then you'd find yourself writing services with observables so that your components could subscribe to changes in the data. Eventemitters already give you this pattern with @Output as shown above.

If it were a simple parent -> child communication, this is unnecessary overhead, and should be avoided.

That said, if you find yourself using services to manage global state, you'd be better off using some form of state management such as ngrx


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...