代码之家  ›  专栏  ›  技术社区  ›  Miomir Dancevic

共享服务示例Angular 5

  •  0
  • Miomir Dancevic  · 技术社区  · 6 年前

    我知道这个问题已经被问过好几次了,但问题是没有人试图做一些改动或显示代码的结果。这就是我所拥有的,我需要根据其他组件中的值更新其他组件中的值,但这不仅仅是值,我还需要在其他组件中再次调用函数。 我有一些组件转到数据库并更新值,另一方面,我有其他组件从服务数据库读取这些值。 这是我的代码示例

    任务.服务.ts

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/operator/map';
    import { environment } from '../../environments/environment';
    import { Tasks } from './tasks';
    
    @Injectable()
    export class TasksProvider {
    
        constructor(private http: HttpClient) { }
    
        createNewTask(name: Name) : Observable<any> {
            return this.http.post(environment.apiUri + 'tasks', { name, finished: false },
             { responseType: 'text' });
        }
    
        updateTask(id: Id, name: Name, finished: boolean) : Observable<any> {
            return this.http.put(environment.apiUri + 'tasks/' + id, { name, finished },
             { responseType: 'text' });
        }
    
        getAllTasks(): Observable<Tasks[]> {
            return this.http.get(environment.apiUri + 'tasks')
                .map<any, Tasks[]>(data => data.map(Tasks.fromObject));
        }
    }
    

    app.component.html(应用程序组件.html)

    <app-tasks-list></app-tasks-list>
    <app-tasks-add-new></app-tasks-add-new>
    

    正如你可能看到的,我没有儿童组件,这是我的主要问题

    任务-list.component.ts

    import {Component} from '@angular/core';
    
    import { Tasks } from '../services/tasks';
    import { TasksProvider } from '../services/tasks.service'; 
    
    @Component({
      selector: 'app-tasks-list',
      templateUrl: './tasks-list.component.html',
      styleUrls: ['./tasks-list.component.scss']
    })
    
    export class TasksListComponent {
      tasks: Array<Tasks>;
    
      constructor(private tasksProvider: TasksProvider) { }
    
      ngOnInit() { 
        this.getTasksList();
      }
    
      displayedColumns: string[] = ['id', 'name', 'finished'];
      private getTasksList() {
            this.tasksProvider.getAllTasks()
                .subscribe(tasks => {
                    this.tasks = tasks;
                });
      } 
    
      public updateCheckboxValue(id: number, name: string, event: any){
        this.tasksProvider.updateTask(id, name, event.checked).subscribe(
          result => {},
          () => {
            alert('Something went wrong');
          })
      }
    }
    

    任务-add-new.component.ts

    import { Component, OnInit, Inject } from '@angular/core';
    import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
    
    import { Tasks } from '../services/tasks';
    import { TasksProvider } from '../services/tasks.service'; 
    
    export interface DialogData {
      name: string;
    }
    
    @Component({
      selector: 'app-tasks-add-new',
      templateUrl: './tasks-add-new.component.html',
      styleUrls: ['./tasks-add-new.component.scss']
    })
    export class TasksAddNewComponent implements OnInit {
    
      ngOnInit() {
      }
    
      constructor(public dialog: MatDialog, private tasksProvider: TasksProvider) {}
    
      openDialog(): void {
        const dialogRef = this.dialog.open(TasksAddNewDialog, {
          width: '250px',
          data: {name: this.animal}
        });
    
        dialogRef.afterClosed().subscribe(result => {
          this.name = result
          this.tasksProvider.createNewTask(this.name).subscribe(
            result => {},
            () => {
              alert('Something went wrong');
            })
      }
    }
    }
    @Component({
      selector: 'tasks-add-new-dialog',
      templateUrl: 'tasks-add-new-dialog.html'
    })
    
    export class TasksAddNewDialog {
      constructor(
        public dialogRef: MatDialogRef<TasksAddNewDialog>,
        @Inject(MAT_DIALOG_DATA) public data: DialogData) {}
    
      onNoClick(): void {
        this.dialogRef.close();
      }
    }
    

    当我调用函数 任务-add-new.component.ts 喜欢

     this.tasksProvider.createNewTask(this.name).subscribe(
            result => {},
            () => {
              alert('Something went wrong');
            })
    

    我需要再次调用函数 任务-list.component.ts

      private getTasksList() {
            this.tasksProvider.getAllTasks()
                .subscribe(tasks => {
                    this.tasks = tasks;
                });
      } 
    

    有没有人知道我怎样才能做到最好?

    1 回复  |  直到 6 年前
        1
  •  1
  •   dhilt    6 年前

    对可能的方法是使用主题。

    1)在服务上存储任务列表并提供可订阅主题

    private tasks: Array<Task>;
    public $tasks: BehaviorSubject<Array<Task>>;
    
    constructor(private http: HttpClient) {
      this.$tasks = new BehaviorSubject([]);
      ...
    }
    
    getAllTasks() {
     this.http.get(environment.apiUri + 'tasks')
        .subscribe(data => {
          this.tasks = data;
          this.$tasks.next(this.tasks);
        });
    }
    
    updateTask(params) {
      this.http.post(/* params */).subscribe((task) => {
        this.tasks = this.tasks.map(t => t.id !== task.id ? t : task);
        this.$tasks.next(this.tasks);
      });
    }
    
    createTask(...) {
      // again, do a request, update this.tasks and call $tasks.next
      ...
    }
    

    2)在组件上订阅一个服务主题,而不是多个可观察的服务方法监听器,每次更改服务源时自动更新组件列表。

    tasks: Array<Tasks>;
    
    constructor(private tasksProvider: TasksProvider) {
      this.tasksProvider.$tasks.subscribe(tasks => this.tasks = tasks);
    }
    
    ngOnInit() { 
      this.tasksProvider.getAllTasks();
    }
    
    public updateCheckboxValue(id: number, name: string, event: any){
      this.tasksProvider.updateTask(id, name, event.checked);
    }