将数据从两个组件传输到服务(角度2)

时间:2017-07-05 10:30:51

标签: javascript angular typescript

我最近在angular2中,我制作了2个组件(users.component和tasks.component),它们应该将数据传递给服务,它会执行一些操作并将其传递给父组件。

users.component.ts

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

  @Component({
    selector: 'users',
    templateUrl: 'app/users.component.html',
    styleUrls: ['app/users.component.css']
  })
  export class UsersComponent {
    usersArr: any[] = [];

    designUsers: any[] = [];
    frontendUsers: any[] = [];
    backendUsers: any[] = [];

    addUsersRow(): void {
      this.usersArr.push({});
    }

    recountUsers(i: number, userSpec: any): void {

            if (userSpec === 'd' || userSpec === 'D') {
                this.designUsers.push(this.usersArr[i]);
            } else if (userSpec === 'f' || userSpec === 'F') {
                this.frontendUsers.push(this.usersArr[i]);
            } else if (userSpec === 'b' || userSpec === 'B') {
                this.backendUsers.push(this.usersArr[i]);
            }

            for (let j = 0; j < this.designUsers.length; j++) {
              if (this.designUsers[j].spec == 'f' || this.designUsers[j].spec == 'b') {
                this.designUsers.splice(j, 1);
              }
            }

            for (let j = 0; j < this.frontendUsers.length; j++) {
              if (this.frontendUsers[j].spec == 'b' || this.frontendUsers[j].spec == 'd') {
                this.frontendUsers.splice(j, 1);
              }
            }

            for (let j = 0; j < this.backendUsers.length; j++) {

              if (this.backendUsers[j].spec == 'f' || this.backendUsers[j].spec == 'd') {
                this.backendUsers.splice(j, 1);
              }
            }

    }

    usersName(i: number, userName: any): void {
      this.usersArr[i].name = userName;
    }

    usersSpec(i: number, userSpec: any): void {

        this.usersArr[i].spec = userSpec;

        this.recountUsers(i, userSpec);
    }

    usersPrice(i: number, userPrice: any): void {
      this.usersArr[i].price = userPrice;
    }
  }

users.component.html

<div class="addUser" id="addUser">
                <h1>USER</h1>
                <button class="addUser__button" id="addUserButton" type="button" (click)="addUsersRow()">Добавить USER</button>
                <div class="addUser__input" *ngFor="let rowUsers of usersArr; let i=index">{{i}}
                    <input class="addUser__input-name" type="text" placeholder=" Имя: Петр" (change)="usersName(i, userName.value)" #userName required>
                    <input class="addUser__input-spec" type="text" placeholder=" Специализация: f/b/d" maxlength="1" pattern="[dbfDBF]" (change)="usersSpec(i, userSpec.value)" #userSpec required>
                    <input class="addUser__input-price" type="number" placeholder=" Цена: 2000" min="0" (change)="usersPrice(i, userPrice.value)" #userPrice required>
                </div>
            </div>

tasks.component.ts

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

        @Component({
            selector: 'tasks',
            templateUrl: 'app/tasks.component.html',
            styleUrls: ['app/tasks.component.css']
        })
        export class TasksComponent {
            tasksArr: any[] = [];

            designTasks: any[] = [];
            frontendTasks: any[] = [];
            backendTasks: any[] = [];

            addTasksRow(): void {
              this.tasksArr.push({});
            }

            recountTasks(i: number, taskSpec: any): void {

                if (taskSpec == 'd' || taskSpec == 'D') {
                    this.designTasks.push(this.tasksArr[i]);
                } else if (taskSpec == 'f' || taskSpec == 'F') {
                    this.frontendTasks.push(this.tasksArr[i]);
                } else if (taskSpec == 'b' || taskSpec == 'B') {
                    this.backendTasks.push(this.tasksArr[i]);
                }

                for (let j = 0; j < this.designTasks.length; j++) {
                  if (this.designTasks[j].spec == 'f' || this.designTasks[j].spec == 'b') {
                    this.designTasks.splice(j, 1);
                  }
                }

                for (let j = 0; j < this.frontendTasks.length; j++) {
                  if (this.frontendTasks[j].spec == 'b' || this.frontendTasks[j].spec == 'd') {
                    this.frontendTasks.splice(j, 1);
                  }
                }

                for (let j = 0; j < this.backendTasks.length; j++) {

                  if (this.backendTasks[j].spec == 'f' || this.backendTasks[j].spec == 'd') {
                    this.backendTasks.splice(j, 1);
                  }
                }
            }

            tasksSpec(i: number, taskSpec: any): void {

                this.tasksArr[i].spec = taskSpec;

                this.recountTasks(i, taskSpec);

                console.log('tasksArr:');
                console.log(this.tasksArr);
            }

            tasksHours(i: number, taskHours: any): void {
                this.tasksArr[i].hours = taskHours;
            }
        }

tasks.component.html

<div class="addTask" id="addTask">
                    <h1>TASK</h1>
                    <button class="addTask__button" id="addTaskButton" type="button" (click)="addTasksRow();">Добавить TASK</button>
                    <div class="addTask__input" *ngFor="let rowTasks of tasksArr; let i=index">{{i}}
                        <input class="addTask__input-spec" type="text" placeholder=" Специализация: f/b/d" maxlength="1" pattern="[dbfDBF]" (change)="tasksSpec(i, taskSpec.value)" #taskSpec required>
                        <input class="addTask__input-hours" type="number" placeholder=" Часы: 20" min="0" (change)="tasksHours(i, taskHours.value)" #taskHours required>
                    </div>
                </div>

compare.service.ts

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

@Injectable()
export class CompareService {
    code...         
}

我想实现这个结构: enter image description here

来自users.component我需要使用designUsers,frontendUsers和backendUsers,以及来自designTasks等任务(每个数组)。问题是,是否有可能实施这样的结构,如果没有,请帮助我们了解如何实现这一想法,谢谢。

1 个答案:

答案 0 :(得分:0)

查看此plunkr示例。有两个子组件,都可以改变某些服务的状态。

@Component({
  selector: 'child1',
  template: `
      <button (click)="handle()">child 1</button>
  `,
})
export class Child1Component {
  constructor(private service: Service) {}

  handle() {
    this.service.child1State = true;
  }
}

有一个parrent组件订阅了服务的状态更改:

@Component({
  selector: 'my-app',
  template: `
    <div>{{state}}</div>
    <child1></child1>
    <child2></child2>
  `,
})
export class App implements OnInit {
  state = 'unset';

  constructor(private service: Service) {}

  ngOnInit() {
    this.service.observable.subscribe(val => {
      if (val) {
        this.state = 'set';
      } else {
        this.state = 'unset';
      }
    });
  }
}

这是服务。它会在每次更改后检查状态,并在需要时通知订户组件:

@Injectable()
export class Service {
  private _child1State = false;
  private _child2State = false;
  private subject = new Subject<boolean>;
  observable = this.subject.asObservable();

  set child1State(val: boolean) {
    this._child1State = val;
    if (this.isAllSet()) {
      this.subject.next(true);
    }
  }

  set child2State(val: boolean) {
    this._child2State = val;
    if (this.isAllSet()) {
      this.subject.next(true);
    }
  }

  private isAllSet(): boolean {
    return this._child1State && this._child2State;
  }
}