【Angular】组件之间的值传递

传递组件之间的值
适用于希望先运行示例并学习的人。
详细解释留给链接或读者自行搜索。
虽然使用了Angular Material,但不详述。

交付方式

使用Input和Output
使用service
使用RxJS
附加到URL

我认为只要使用这些中的任何一个,问题都能够解决。

使用输入和输出

当父组件包含子组件时才有效。即当子组件被嵌入在父组件中时。

了解Angular中的@Input()、@Output()。
【Angular】组件之间数据的传递方法。

亲组件

<div class="parent">
    <!-- app-parts-inputは子コンポーネント -->
    <app-parts-input 
        [ctrName]="this.form" ph="名前を入力" la="名前"
    ></app-parts-input>
</div>
import { Component, OnInit } from '@angular/core';
import { FormControl } from "@angular/forms";

export class DataToSendComponent implements OnInit {
  form: FormControl;

  constructor() { }

  ngOnInit() {
    this.form = new FormControl("");
  }
}

子组件

<mat-form-field>
  <mat-label>{{ this.la }}</mat-label>
  <input
    matInput [placeholder]="ph" [formControl]="ctrName" (keyup)="output()"
  />
</mat-form-field>
import { Component, Input } from "@angular/core";
import { AbstractControl } from "@angular/forms";

export class InputPartsComponent {
  @Input() ctrName: AbstractControl;
  @Input() ph: string;
  @Input() la: string;

  constructor() { }

  output() {
    console.log(this.ctrName.value);
  }
}
スクリーンショット 2020-06-19 14.22.22.png

我们将`formControl`、`placeholder`的值以及`label`的值从父组件(灰色)传递给子组件(白色),并在子组件中使用。

下一步是在上面的代码基础上,尝试从子组件向父组件传递值,通过Output实现。

亲组件

<div class="parent">
    <app-parts-input [ctrName]="this.form" ph="名前を入力" la="名前" (childEvent)="getString($event)"></app-parts-input>
    <p>{{this.text}}</p>
</div>
import { Component, OnInit } from '@angular/core';
import { FormControl } from "@angular/forms";

export class DataToSendComponent implements OnInit {
  form: FormControl;
  text: string;
  constructor() { }

  ngOnInit() {
    this.form = new FormControl("");
  }

  getString(event: string) {
    console.log(event);
    this.text = event;
  }
}

子组件 (zǐ

html変更なし
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { AbstractControl } from "@angular/forms";

export class InputPartsComponent {
  @Input() ctrName: AbstractControl;
  @Input() ph: string;
  @Input() la: string;
  @Output() childEvent = new EventEmitter<string>();
  constructor() { }

  output() {
    this.childEvent.emit(this.ctrName.value);//<-イベントを発火
  }
}
スクリーンショット 2020-06-19 14.36.47.png

使用服务

参考
添加Angular日本语文档服务
[Angular] 使用Angular CLI生成服务

服务

//service
import { Injectable } from "@angular/core";

@Injectable({
  providedIn: "root"
})
export class CommonService {
  messege: string;

  constructor() {}

  setMessege(text: string) {
    this.messege = text;
  }
  getMessege() {
    return this.messege;
  }
}

亲组件

<!-- html -->
<div class="parent">
  <h4>親コンポーネント</h4>
  <app-test></app-test>
</div>

//ts
import { Component } from "@angular/core";
import { CommonService } from "./common.service";

@Component({
  selector: "app-root",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.scss"]
})
export class ParentComponent {
  parentMessege = "親からのメッセージ";

  constructor(private commonService: CommonService) {
    this.commonService.setMessege(this.parentMessege);//<-サービスにメッセージをセット
  }
}

组件子类别

<!-- html -->
<div class="child">
  <h4>子コンポーネント</h4>
  <button (click)="onClick()">メッセージを取得</button>
  <p>メッセージ:{{ messege }}</p>
</div>
import { Component, OnInit } from "@angular/core";
import { CommonService } from "../common.service";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.scss"]
})
export class ChildComponent implements OnInit {
  messege: string;
  constructor(private commonService: CommonService) {}
  ngOnInit() {}
  onClick() {
    this.messege = this.commonService.getMessege();//<-サービス上の値を取得する
  }
}
スクリーンショット 2020-04-01 16.20.53.png

使用RxJS

参考:整理RxJS的基础知识
在Angular中停止Observable(流)的订阅方法

在先前的服務例子中,儘管可以進行交付本身,
但無法在值被放入時,將值傳遞並反映在組件之間,這樣的處理無法實現。
在服務中需要按下按鈕這個動作。
要在值被放入時實現傳遞,可以使用RxJS來實現。

用于演示的样例是,将输入的值逐个字符地发送到其他组件。我们需要准备两个组件:①用于显示输入的组件,②用于显示接收到的值的组件。还需要一个用于使用RxJS的服务。

<!-- ①html -->
<div class="parent">
    <mat-form-field>
        <mat-label>名前</mat-label>
        <input matInput placeholder="名前" [formControl]="form" (keyup)="output()" />
    </mat-form-field>
    <app-child></app-child>
</div>
// ①ts
import { Component, OnInit } from '@angular/core';
import { FormControl } from "@angular/forms";
import { 
   ObservableSampleService
 } from "../../service/observable-sample.service";

export class ObservableComponent implements OnInit {
  form: FormControl;
  constructor(private obss: ObservableSampleService) { }

  ngOnInit() {
    this.form = new FormControl("");
  }

  output() {
    this.obss.testSubject.next(this.form.value);
  }
}
<!-- ②html -->
<p>{{this.text}}</p>
//②ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subscription } from "rxjs";
import { 
   ObservableSampleService
} from "../../../service/observable-sample.service";

export class ChildComponent implements OnInit, OnDestroy {

  Obs: Observable<string>;
  Subs: Subscription;
  text: string;
  constructor(private obss: ObservableSampleService) { }

  ngOnInit() {
    this.Obs = this.obss.testSubject$;
    this.Subs = this.Obs.subscribe(str => {
      this.text = str;
    });
  }

  ngOnDestroy() {
    if (this.Subs) {
      this.Subs.unsubscribe();
    }
  }
}
//service
import { Injectable } from '@angular/core';
import { Subject } from "rxjs";
@Injectable({
  providedIn: 'root'
})
export class ObservableSampleService {
  testSubject = new Subject<string>();
  constructor() { }

  get testSubject$() {
    return this.testSubject.asObservable();
  }
}
スクリーンショット 2020-06-19 16.14.00.png

在网址之后添加

使用路由来添加应用内导航。

当需要创建每个id的页面时等等。
当点击链接时,获取并显示与指定id相对应的信息的示例。

我們將提供一個組件來顯示鏈接,一個組件來顯示用戶信息,以及一個服務來返回數據庫的信息。

//app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";
import { UserInfoComponent } from "./user-info/user-info.component";
import { Routes, RouterModule } from "@angular/router";
import { DefaultComponent } from "./default/default.component";

const routes: Routes = [
  { path: "", component: DefaultComponent },
  { path: "user-info/:id", component: UserInfoComponent } // <-/:id 追加
];
@NgModule({
  declarations: [AppComponent, UserInfoComponent, DefaultComponent],
  imports: [BrowserModule, RouterModule.forRoot(routes)],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

<!-- app.component.html -->
<router-outlet></router-outlet>
//info.service
import { Injectable } from "@angular/core";

@Injectable({
  providedIn: "root"
})
export class InfoService {
  user = [
    { id: 1111, name: "花子" },
    { id: 1112, name: "太郎" }
  ];
  constructor() {}
  getUser(id: number) {//idが一致するユーザーの情報を返却する
    for (let i in this.user) {
      if (this.user[i].id === id) {
        return this.user[i];
      }
    }
  }
}
<!-- user-info.component.html -->
<p>私の名前は{{ userinfo.name }}です。</p>
//user-info.component.ts
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { InfoService } from "src/app/service/info.service";
@Component({
  selector: "app-user-info",
  templateUrl: "./user-info.component.html",
  styleUrls: ["./user-info.component.scss"]
})
export class UserInfoComponent implements OnInit {
  userinfo;
  constructor(
    private infoservice: InfoService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.userinfo = this.getInfo();
  }

  /**
   * URLのidを元にデータを取得
   */
  getInfo() {
    const id = this.route.snapshot.paramMap.get("id");
    return this.infoservice.getUser(Number(id));
  }
}
スクリーンショット 2020-04-03 8.21.07.png

希望这些是一个基础操作示例,能够成为大家理解的起点。

bannerAds