前几天在利用ngx-translate做多语言的时候遭逢了3个标题,要求在报到页面点击按键,然后调用父组件中的三个主意。

单页面应用组件通讯有以下三种,那篇文章首要讲 Angular 通信

1初步想到了@input和@output,但是由于并不是只是的老爹和儿子组件关系,而是包含路由的父亲和儿子组件关系,所以并无法运用@input方法和@output方法。

永利开户送38元体验金 1

然后去找出一下,开采stackoverflow上有答案,用的是service来举办传参,开掘很好用,所以和豪门享用一下。

  • 父组件 => 子组件
  • 子组件 => 父组件
  • 组件A = > 组件B

先是,成立3个service.

父组件 => 子组件 子组件 => 父组件 sibling => sibling
@input @output
setters (本质上还是@input) 注入父组件
ngOnChanges() (不推荐使用)
局部变量
@ViewChild()
service service service
Rxjs的Observalbe Rxjs的Observalbe Rxjs的Observalbe
localStorage,sessionStorage localStorage,sessionStorage localStorage,sessionStorage

shared-service.ts

地点图表总括了能用到通讯方案,期中最终三种,是通用的,angular的零件之间都能够动用那叁种,个中路虎极光xjs是最最牛逼的用法,甩redux,promise,那些同样基于函数式的图景管理几条街,上面壹1说来

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SharedService {
    // Observable string sources
    private emitChangeSource = new Subject<any>();
    // Observable string streams
    changeEmitted$ = this.emitChangeSource.asObservable();
    // Service message commands
    emitChange(change: any) {
        this.emitChangeSource.next(change);
    }
}

父组件 => 子组件

接下来把那一个service分别注入父组件和子组件所属的module中,记得要放在providers里面。
接下来把service再引进到父亲和儿子组件各自的component里面。
子组件通过onClick方法传递参数:

@input,最常用的一种艺术

child.component.ts

@Component({
 selector: 'app-parent',
template: '<div>childText:<app-child [textContent] = "varString"></app-child></div>',
 styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
 varString: string;
 constructor() { }
 ngOnInit() {
  this.varString = '从父组件传过来的' ;
 }
}


import { Component, OnInit, Input } from '@angular/core';
@Component({
 selector: 'app-child',
 template: '<h1>{{textContent}}</h1>',
 styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
 @Input() public textContent: string ;
 constructor() { }
 ngOnInit() {
 }
}
import { Component} from '@angular/core';
@Component({
    templateUrl: 'child.html',
    styleUrls: ['child.scss']
})
export class ChildComponent {
    constructor(
        private _sharedService: SharedService
    ) { }

onClick(){
  this._sharedService.emitChange('Data from child');

 }
}

setter

父组件通过服务收取参数:

setter 是阻止@input
属性,因为大家在组件通讯的时候,日常必要对输入的属性管理下,就须要setter了,setter和getter常配套使用,稍微修改下方面包车型地铁child.component.ts

永利开户送38元体验金,parent.component.ts

child.component.ts

import { Component} from '@angular/core';
@Component({
    templateUrl: 'parent.html',
    styleUrls: ['parent.scss']
})
export class ParentComponent {
    constructor(
        private _sharedService: SharedService
    ) {
          _sharedService.changeEmitted$.subscribe(
        text => {
            console.log(text);
        });
      }

}
import { Component, OnInit, Input } from '@angular/core';
@Component({
 selector: 'app-child',
 template: '<h1>{{textContent}}</h1>',
 styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
_textContent:string;
 @Input()
 set textContent(text: string){
  this._textContent = !text: "啥都没有给我" ? text ;
 } ;
 get textContent(){
 return this._textContent;
 }
 constructor() { }
 ngOnInit() {
 }
}

原稿地址:

onChange

本条是通过angular生命周期钩子来检查评定,不推荐应用,要采用的话能够参angular文档

@ViewChild()

@ViewChild() 一般用在调用子组件非私有的主意

      import {Component, OnInit, ViewChild} from '@angular/core';
    import {ViewChildChildComponent} from "../view-child-child/view-child-child.component";
  @Component({
   selector: 'app-parent',
   templateUrl: './parent.component.html',
   styleUrls: ['./parent.component.css']
  })
  export class ParentComponent implements OnInit {
   varString: string;
   @ViewChild(ViewChildChildComponent)
   viewChildChildComponent: ViewChildChildComponent;
   constructor() { }
   ngOnInit() {
    this.varString = '从父组件传过来的' ;
   }
   clickEvent(clickEvent: any) {
    console.log(clickEvent);
    this.viewChildChildComponent.myName(clickEvent.value);
   }
  }


   import { Component, OnInit } from '@angular/core';
  @Component({
   selector: 'app-view-child-child',
   templateUrl: './view-child-child.component.html',
   styleUrls: ['./view-child-child.component.css']
  })
  export class ViewChildChildComponent implements OnInit {
   constructor() { }
   name: string;
   myName(name: string) {
     console.log(name);
     this.name = name ;
   }
   ngOnInit() {
   }
  }

一些变量

有个别变量和viewChild类似,只可以用在html模板里,修改parent.component.html,通过#viewChild这么些变量来表示子组件,就会调用子组件的办法了.

<div class="panel-body">
  <input class="form-control" type="text" #viewChildInputName >
  <button class=" btn btn-primary" (click)="viewChild.myName(viewChildInputName.value)">局部变量传值</button>
  <app-view-child-child #viewChild></app-view-child-child>
      </div>

child 组件如下

@Component({
 selector: 'app-view-child-child',
 templateUrl: './view-child-child.component.html',
 styleUrls: ['./view-child-child.component.css']
})
export class ViewChildChildComponent implements OnInit {

 constructor() { }
 name: string;
 myName(name: string) {
   console.log(name);
   this.name = name ;
 }
 ngOnInit() {
 }

}

子组件 => 父组件

@output()

output这种大规模的通讯,本质是给子组件传入二个function,在子组件里施行完有些方法后,再实施传入的那么些回调function,将值传给父组件

parent.component.ts

@Component({
 selector: 'app-child-to-parent',
 templateUrl: './parent.component.html',
 styleUrls: ['./parent.component.css']
})
export class ChildToParentComponent implements OnInit {

 childName: string;
 childNameForInject: string;
 constructor( ) { }
 ngOnInit() {
 }
 showChildName(name: string) {
  this.childName = name;
 }
}

parent.component.html

<div class="panel-body">
 <p>output方式 childText:{{childName}}</p>
 <br>
 <app-output-child (childNameEventEmitter)="showChildName($event)"></app-output-child>
</div>
 child.component.ts
 export class OutputChildComponent implements OnInit {
 // 传入的回调事件
 @Output() public childNameEventEmitter: EventEmitter<any> = new EventEmitter();
 constructor() { }
 ngOnInit() {
 }
 showMyName(value) {
  //这里就执行,父组件传入的函数
  this.childNameEventEmitter.emit(value);
 }
}

流入父组件

那个规律的原故是父,子组件本质生命周期是1致的

export class OutputChildComponent implements OnInit {
 // 注入父组件
 constructor(private childToParentComponent: ChildToParentComponent) { }
 ngOnInit() {
 }
 showMyName(value) {
  this.childToParentComponent.childNameForInject = value;
 }
}

sibling组件 => sibling组件

service

Rxjs

通过service通信

angular中service是单例的,所以几种通讯项目都能够经过service,许多前端对单例精通的不是很清楚,本质正是
,你在某些module中流入service,全部这几个modul的component都足以获得那一个service的本性,方法,是共享的,所以常在app.moudule.ts注入日志service,http拦截service,在子module注入的service,只好那么些子module能共享,在component注入的service,就只可以子的component的能得到service,上边以注入到app.module.ts,的service来演示

user.service.ts

@Injectable()
export class UserService {
 age: number;
 userName: string;
 constructor() { }
}

app.module.ts

@NgModule({
 declarations: [
  AppComponent,
  SiblingAComponent,
  SiblingBComponent
 ],
 imports: [
  BrowserModule
 ],
 providers: [UserService],
 bootstrap: [AppComponent]
})
export class AppModule { }
SiblingBComponent.ts
@Component({
 selector: 'app-sibling-b',
 templateUrl: './sibling-b.component.html',
 styleUrls: ['./sibling-b.component.css']
})
export class SiblingBComponent implements OnInit {
 constructor(private userService: UserService) {
  this.userService.userName = "王二";
 }
 ngOnInit() {
 }
}

SiblingAComponent.ts

@Component({
 selector: 'app-sibling-a',
 templateUrl: './sibling-a.component.html',
 styleUrls: ['./sibling-a.component.css']
})
export class SiblingAComponent implements OnInit {
 userName: string;
 constructor(private userService: UserService) {
 }
 ngOnInit() {
  this.userName = this.userService.userName;
 }
}

通过Rx.js通信

这么些是最牛逼的,基于订阅发布的这种流文件管理,1旦订阅,发表的源头产生变动,订阅者就能够得到那么些转变;那样说不是很好通晓,轻巧解释正是,b.js,c.js,d.js订阅了a.js里某些值变化,b.js,c.js,d.js立马获取到那几个变化的,但是a.js并不曾积极性调用b.js,c.js,d.js那么些里面包车型大巴法子,举个轻易的事例,各样页面在管理ajax请求的时候,都有一弹出的提醒消息,一般小编会在
组件的template中中放三个提示框的零部件,那样很麻烦每一个组件都要来一次,即使基于Lacrossex.js,就可以在app.component.ts中放这么些指示组件,然后app.component.ts订阅公共的service,就比较便利了,代码如下

先是搞贰个alset.service.ts

import {Injectable} from "@angular/core";
import {Subject} from "rxjs/Subject";
@Injectable()
export class AlertService {
 private messageSu = new Subject<string>(); //
 messageObserve = this.messageSu.asObservable();
 private setMessage(message: string) {
  this.messageSu.next(message);
 }
 public success(message: string, callback?: Function) {
  this.setMessage(message);
  callback();
 }
}

sibling-a.component.ts

@Component({
 selector: 'app-sibling-a',
 templateUrl: './sibling-a.component.html',
 styleUrls: ['./sibling-a.component.css']
})
export class SiblingAComponent implements OnInit {
 userName: string;
 constructor(private userService: UserService, private alertService: AlertService) {
 }
 ngOnInit() {
  this.userName = this.userService.userName;
  // 改变alertService的信息源
  this.alertService.success("初始化成功");
 }
}

app.component.ts

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 title = 'app';
 message: string;
 constructor(private alertService: AlertService) {
  //订阅alertServcie的message服务
   this.alertService.messageObserve.subscribe((res: any) => {
   this.message = res;
  });
 }
}

那样订阅者就能够动态的跟着公布源变化

小结:
以上正是常用的的通讯情势,各样场地能够采取两样的办法。希望对我们的学习抱有支持,也可望大家多多帮衬脚本之家。

你或者感兴趣的篇章:

  • angular4共享服务在多少个零部件中多少通信的演示
  • Angular贰父亲和儿子组件通讯格局的言传身教
  • angular中分歧的机件间传值与通讯的主意
  • Angular
    二父亲和儿子组件之间共享服务通讯的落到实处
  • Angular2组件通讯的实例代码
  • 详解Angular二组件之间什么通讯
  • Angular贰父亲和儿子组件数据通讯实例
  • Angularjs2分化组件间的通信实例代码

相关文章