Hansinger Hansinger - 3 months ago 25
TypeScript Question

Angular2 communication between 2 components

i am using Angular2 rc5 and i try to build a component communication through a service.
For arrays it works like expected but if i change a string its not updating.

My main component looks like:

import {Component} from '@angular/core';
import {ShareServiceService} from "../share-service.service";
import {ChildTwoComponent} from "../child-two/child-two.component";
import {ChildOneComponent} from "../child-one/child-one.component";

@Component({
selector: 'parent',
template: `
<h1>Parent</h1>
<div>
<child-one></child-one>
<child-two></child-two>
</div>
`,
providers: [ShareServiceService],
directives: [ChildOneComponent, ChildTwoComponent]
})
export class ParentComponent {
constructor() {}
}


My first children component:

import {Component} from '@angular/core';
import {ShareServiceService} from "../share-service.service";

@Component({
selector: 'child-one',
template: `
<div style="float:right; width: 45%">
<pre>title: {{title}}</pre>
<pre>title: {{_sharedService.testTitle}}</pre>
<div>
<ul *ngFor="let dataElement of data">
<li>{{dataElement}}</li>
</ul>
</div>
</div>
`
})
export class ChildOneComponent{
data:string[] = [];
title:string;

constructor(public _sharedService:ShareServiceService) {
this.data = this._sharedService.dataArray;
this.title = this._sharedService.testTitle;
}
}


The second children component:

import {Component} from '@angular/core';
import {ShareServiceService} from "../share-service.service";

@Component({
selector: 'child-two',
template: `
<div style="float:left; width: 45%">
<pre>title: {{title}}</pre>
<pre>titleObj: {{titleObj.title}}</pre>
<div>
<ul *ngFor="let dataElement of data">
<li>{{dataElement}}</li>
</ul>
</div>
<input type="text" [(ngModel)]="dataInput"/>
<button (click)="addData()">addData</button>
<button (click)="updateTitle()">updateTitle</button>
</div>
`
})
export class ChildTwoComponent {
dataInput:string = 'Testing data';
data:string[] = [];
title:string;

constructor(public _sharedService:ShareServiceService) {
this.data = this._sharedService.dataArray;
this.title = this._sharedService.testTitle;
}

addData() {
this._sharedService.insertData(this.dataInput);
this.dataInput = '';
}

updateTitle() {
this._sharedService.updateTestTitle(this.dataInput);
this.dataInput = '';
}
}


My service:

import {Injectable} from '@angular/core';

@Injectable()
export class ShareServiceService {
dataArray:string[] = [];
testTitle:string = "should be updated";

insertData(data:string) {
this.dataArray.push(data);
}

updateTestTitle(newTitle:string) {
this.testTitle = {title: newTitle};
}
}


What i try to achieve is, that if i enter something in the input field with binding for "" and press the "updateTitle" that the Title in both components are updated.
But thats doesnt work currently.

if i add my input value to an array, by clicking the "adddata" Button, all works like excepted and my list with data elements shows all elements.

Does someone know why i cant update a string?

Thanks in advance!

Answer

If you copy an object or array you copy a reference. Both (source and destination) point to the same object. If one side modifies the object the other side sees the modification.

If you copy a primitive value (string, number, boolean), the the destination gets a copy of the value and source and destination aren't related in any way.

   // copies a reference
   this.data = this._sharedService.dataArray;
   // copies the value
   this.title = this._sharedService.testTitle;

What you probably want is an observable that emits events when properties in the shared service are modified.

For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

Comments