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();
  }
}

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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?
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??
@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.
@MarkRajcok Thanks! but it is this save to use? Are there any major pitfalls?
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.

4 Comments

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?
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.
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?
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.
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();
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.