Search code examples
angularangular2-templateangular2-directivesangular2-components

Angular 2 RC1: Multiple components, Todo List, adding task update


Developing a todo list that is capable of adding a task. Everything works when all of the code is one component (Tasklist) and one service (Taskservice). However when trying to separate one component to multiple components(Tasklist and Addtask), the table containing the list of tasks does not update on add. Here is our implementation.

TaskList:

import { Component, OnInit, Inject } from '@angular/core';
import { TaskService } from '../task.service';
import { Observable } from 'rxjs/Observable';
import { Task } from '../task';


@Component({
  moduleId: module.id,
  selector: 'app-tasklist',
  providers: [TaskService], 
  template: '

<table>

<tr>
    <td><a>Complete</a></td>
    <td><a>Name</a></td>
    <td><a>Due Date</a></td>
    <td>Option</td>
</tr>

<tr *ngFor="let item of items" [items] = "items">
    <td> 
        <p>  {{item.Name}}  </p>
    </td>
    <td> 
        <p>  {{item.DueDate}}  </p>
    </td>

</tr>

</table>

',
  styleUrls: ['tasklist.component.css']
})
export class TasklistComponent implements OnInit {

  public items : Task[];

  constructor(private service: TaskService ){}

  ngOnInit(){
     this.getTasks();
  }

  getTasks(){
     this.service.Get().subscribe(e => this.items = e);
  }
}

AddTaskComponent:

import { Component, Input} from '@angular/core';
import { TaskService } from '../task.service';
import { TasklistComponent } from '../tasklist/tasklist.component';
import { Task } from '../task';

@Component({
  moduleId: module.id,
  selector: 'app-addtask',
  providers: [TaskService, TasklistComponent],
  directives: [TasklistComponent],
  template: '
 <form> 
    <input type="text" [(ngModel)]="taskname" placeholder="Task name" >
    <input type="text" [(ngModel)]="duedate" placeholder="Due Date" >
    <input type="submit" value="Submit" (click)="addTask()" > 
</form>
 ',
  styleUrls: ['addtask.component.css']
})

export class AddtaskComponent {

  public taskname : string;
  public duedate : string;

  @Input() items:Task[];

  constructor(private service : TaskService){}

  addTask(){
    this.service.Post(this.taskname, this.duedate).subscribe(e=>{
      this.getTasks();
      return e;
    });

    this.taskname = '';
    this.duedate = '';
  }

  getTasks() {
     this.service.Get().subscribe(e => this.items = e);
  }

}

The addTask() method adds it to the list, but does not cause the tasklist to update in the view unless the page refreshed.

The basic question: How can a single component be correctly separated into multiple components without the user refreshing the page?


Solution

  • Don't provide components

     providers: [TaskService, TasklistComponent],
    

    should be

     providers: [TaskService],
    

    Components only go into

    directives: [TasklistComponent]
    

    If you provide the TaskService on every component, then every component will get its own instance. Only provide it once at the root component (AppComponent) or some other common parent of the elements where you want to share the same service instance.