angular2 data binding between service and component properties
Asked Answered
I

3

6

I need some clarification on binding between service and component properties and data binding in angular2

assume i have a service(singleton) and a component

export class Service {
 name = "Luke";
 object = {id:1};
 getName(){return this.name};
 getObject(){return this.object};
}

export class Component implements OnInit{
 name:string;
 object:any;
 constructor(private _service:Service){}
 ngOnInit():any{

   //Is this 2 way binding?
   this.name = this._service.name;
   this.object = this._service.object;

   //Is this copying?
   this.name = this._service.getName();
   this.object = this._service.getObject();
  }
}
Impudence answered 6/4, 2016 at 9:3 Comment(0)
S
7

If you update elements by reference (if you update something into the object property), you will see the updates in the view:

export class Service {
  (...)

  updateObject() {
    this.object.id = 2;
  }
}

If you update elements by value (if you update something into the name property), you won't see the updates in the view:

export class Service {
  (...)

  updateName() {
    this.name = 'Luke1';
  }
}

See this plunkr: https://plnkr.co/edit/w7bS0fAVjOc3utnpD39b?p=preview.

Stirps answered 6/4, 2016 at 11:17 Comment(4)
i see, because in the first case ive created two references pointing towards the same object, while the below i would net to "copy" the property again?Impudence
but wait, does it mean that if I have a reference datatype in a Service Singleton, and create new references pointing towards it in various components, the view will update automatically each time i'm changing it??Impudence
@HanChe, yes, the views will all update automatically, because all of your template bindings are bound to the same/one object. All of your components have their own references, but they all point to the same Singleton service, and then all of the template bindings have their own references, but they all point to the same object within that Singleton. So it all works.Communal
@MarkRajcok Thanks! but it is this save to use? Are there any major pitfalls?Impudence
D
7

Angular binding only works for bindings declared in the view (HTML).

If you want properties in your component being updated when values in a service change, you need to take care of it yourself.

Observables make this easy. See detect change of nested property for component input for an example.

Deprave answered 6/4, 2016 at 9:7 Comment(4)
Hi Günter, thanks for your reply and yes I'm on the observables, but in case of this.name = this._service.name; what does it do, is it then just a simple copy?Impudence
Yes it copies the value once when ngOnInit() is called. If for example the service acquires the data from a remote server using an HTTP request, then there might not yet be a value in this.service.name. If the service later receives the response from the server the component doesn't get the new value.Airfoil
the ngOnInit() was just an example, but then what would the difference be between using this.service.name and this.service.getName()? Is it like in java if I declare name as private in the service to protect it and use getters and setters?Impudence
This only depends on what Service.name and Service.getName() return. The value returned from the property or method are assigned to this.name, that's all. There is no Angular involved. This is just what TypeScript does.Airfoil
S
7

If you update elements by reference (if you update something into the object property), you will see the updates in the view:

export class Service {
  (...)

  updateObject() {
    this.object.id = 2;
  }
}

If you update elements by value (if you update something into the name property), you won't see the updates in the view:

export class Service {
  (...)

  updateName() {
    this.name = 'Luke1';
  }
}

See this plunkr: https://plnkr.co/edit/w7bS0fAVjOc3utnpD39b?p=preview.

Stirps answered 6/4, 2016 at 11:17 Comment(4)
i see, because in the first case ive created two references pointing towards the same object, while the below i would net to "copy" the property again?Impudence
but wait, does it mean that if I have a reference datatype in a Service Singleton, and create new references pointing towards it in various components, the view will update automatically each time i'm changing it??Impudence
@HanChe, yes, the views will all update automatically, because all of your template bindings are bound to the same/one object. All of your components have their own references, but they all point to the same Singleton service, and then all of the template bindings have their own references, but they all point to the same object within that Singleton. So it all works.Communal
@MarkRajcok Thanks! but it is this save to use? Are there any major pitfalls?Impudence
S
0

If you want properties in a component updates as soon as a value in change in a service changes:

  1. Import DoCheck from @angular/core and your service into the component.
  2. Call the service functions affecting the component property in ngDoCheck(){...}
  3. The component view will be updated automatically as soon as any changes

Something like this in your component:

  ngDoCheck() {
    this.qty = this.cartService.getTotalQtyInCart();
  }
Stauder answered 4/2, 2018 at 5:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.