GVKun编程网logo

Angular4学习笔记——组件之间的交互(angular组件之间通信)

29

对于Angular4学习笔记——组件之间的交互感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解angular组件之间通信,并且为您提供关于Angular8学习(七进阶)组件之间的传值问题、A

对于Angular4学习笔记——组件之间的交互感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解angular组件之间通信,并且为您提供关于Angular 8 学习 (七 进阶) 组件之间的传值问题、Angular 组件之间的交互的示例代码、Angular 组件之间的传值、angular1.5 组件学习 -- 2.1、组件间的交互:父向子的宝贵知识。

本文目录一览:

Angular4学习笔记——组件之间的交互(angular组件之间通信)

Angular4学习笔记——组件之间的交互(angular组件之间通信)

通过输入型绑定把数据从父组件传到子组件

Angular对于父组件 => 子组件的数据通信做法和Vue很相似。

// 父组件html模板
<app-hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </app-hero-child>
// 子组件接收数据
import { Component,Input } from '@angular/core';
import { Hero } from './hero';

export class HeroChildComponent {
  @input() hero: Hero;
  @Input('master') masterName: string;
}
// 第二个@Input为子组件的属性名masterName指定一个别名master,但是这个做法并不推荐

看着是不是很眼熟,写代码的逻辑和Vue几乎可以说是一样了,只是写法上略有区别而已。

这个问题下还有两个截听输入属性值变化的方法,代码逻辑不难推,但是其中的应用场景方面我还没想到是怎么样的,之后也许继续看Angular文档会理解的更透彻一些,届时再来补充啦~~

父组件监听子组件的事件

这个操作方法也和Vue中的做法非常接近,而且在上一篇笔记中也有所提及。
具体思路:子组件暴露一个EventEmitter属性,当事件发生时,子组件利用该属性emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。
还有,子组件的EventEmitter属性是一个输出属性,通常带有@Output装饰器,比较完整的示例如下:

// 子组件:先在自己的组件中触发了Vote方法,然后在Vote方法中向父组件发出onVoted事件,同时传送一个payload(agreed)
// 在Vue中的写法是this.$emit(onVoted,agreed)
import { Component,EventEmitter,Input,Output } from '@angular/core';

export class VoterComponent {
  @input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  Voted = false;
 
  Vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.Voted = true;
  }
}
// 父组件:监听onVoted事件,如果监听到了则触发自己组件中的agree方法,同时通过$event把payload传参给agree
html:
<app-Voter (onVoted)="onVoted($event)"></app-Voter>
ts:
export class VoteTakerComponent {
  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}

父子组件的其他互动关系

父组件与子组件通过本地变量互动

父组件对子组件的数据绑定属于单向绑定,子组件无法直接把数据、属性和自身的方法传送给父组件使用。尽管有EventEmitter属性,但是有时候需要直接访问子组件的内容,用这种方法并不合适。

// 可以在父组件的模板中直接访问子组件的所有属性和方法,例如此例便是直接访问了子组件的start(),stop()方法和seconds属性
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div>{{timer.seconds}}</div>
<app-countdown-timer #timer></app-countdown-timer>

父组件调用@ViewChild()

上述方法有一定局限性:父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。如果想要在代码中直接访问子组件的内容,可以使用这个方法把子组件作为ViewChild,注入到父组件里面,具体操作如下:

// 需要通过@ViewChild属性装饰器,将子组件CountdownTimerComponent注入到私有属性timerComponent里面,并挂在AfterViewInit生命周期钩子里
export class CountdownViewChildParentComponent implements AfterViewInit {
// 在父组件中将子组件注册为变量timerComponent,记得在括号里写明子组件名字~~ 
  @ViewChild(CountdownTimerComponent)  private timerComponent: CountdownTimerComponent;
// 这样就可以通过this.timerComponent访问子组件的内容了
  start() { this.timerComponent.start(); }
  stop() { this.timerComponent.stop(); }
}

通过服务来通讯

父组件和它的子组件(们)共享同一个服务,利用该服务在父子组件之间实现双向通讯。
该服务实例的作用域被限制在父组件和其子组件(们)内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。

父子组件通过各自的构造函数注入该服务。文档中的例子还需要一些额外知识才能明白,之后再分析啦!~

前端新人,写的不对的地方还请指出;如果觉得对你有帮助,可以点个赞鼓励一下我哦!~~

Angular 8 学习 (七 进阶) 组件之间的传值问题

Angular 8 学习 (七 进阶) 组件之间的传值问题

一、父组件给子组件传值

@input

在父组件中定义要传递给子组件的数据:

父组件中在调用子组件的时候在子组件中添加要传递的数据

子组件接受参数

子组件引入

参数

方法

二、父组件获得子组件的数据方法(在这里介绍@viewchild)

给组件定义别名:

引入viewchild

组件关联

调用:

总结

以上是小编为你收集整理的Angular 8 学习 (七 进阶) 组件之间的传值问题全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

原文地址:https://blog.csdn.net/luodong1501/article/details/100145204

Angular 组件之间的交互的示例代码

Angular 组件之间的交互的示例代码

在Angular应用开发中,组件可以说是随处可见的。本篇文章将介绍几种常见的组件通讯场景,也就是让两个或多个组件之间交互的方法。

根据数据的传递方向,分为父组件向子组件传递、子组件向父组件传递及通过服务传递三种交互方法。

父组件向子组件传递

子组件通过@Input装饰器定义输入属性,然后父组件在引用子组件的时候通过这些输入属性向子组件传递数据,子组件可通过setter或ngOnChanges()来截听输入属性值的变化。

先定义两个组件,分别为子组件DemoChildComponent和父组件DemoParentComponent.

子组件:

rush:js;"> @Component({ selector: 'demo-child',template: `

{{paramOne}}

{{paramTwo}}

` }) export class DemoChildComponent { @input() paramOne: any; // 输入属性1 @input() paramTwo: any; // 输入属性2 }

子组件通过@input()定义输入属性paramOne和paramTwo(属性值可以为任意数据类型)

父组件:

rush:js;"> @Component({ selector: 'demo-parent',template: ` ` }) export class DemoParentComponent { paramOneVal: any = '传递给paramOne的数据'; paramTwoval: any = '传递给paramTwo的数据'; }

父组件在其模板中通过选择器demo-child引用子组件DemoChildComponent,并通过子组件的两个输入属性paramOne和paramTwo向子组件传递数据,最后在子组件的模板中就显示传递给paramOne的数据和传递给paramTwo的数据这两行文本。

通过 setter 截听输入属性值的变化

在实际应用中,我们往往需要在某个输入属性值发生变化的时候做相应的操作,那么此时我们需要用到输入属性的 setter 来截听输入属性值的变化。

我们将子组件DemoChildComponent进行如下改造:

rush:js;"> @Component({ selector: 'demo-child',template: `

{{paramOneVal}}

{{paramTwo}}

` }) export class DemoChildComponent { private paramOneVal: any;

@input()
set paramOne (val: any) { // 输入属性1
this.paramOneVal = val;
// dosomething
};
get paramOne () {
return this.paramOneVal;
};

@input() paramTwo: any; // 输入属性2
}

在上面的代码中,我们可以看到通过paramOne属性的 setter 将拦截到的值val赋值给内部私有属性paramOneVal,达到父组件传递数据给子组件的效果。当然,最重要的是,在 setter 里面你可以做更多的其它操作,程序的灵活性就更强了。

通过ngOnChanges()来截听输入属性值的变化

通过 setter 截听输入属性值的变化的方法只能对单个属性值变化进行监视,如果需要监视多个、交互式输入属性的时候,这种方法就显得力不从心了。而通过使用 OnChanges 生命周期钩子接口的 ngOnChanges() 方法(当组件通过@Input装饰器显式指定的那些变量的值变化时调用)就可以实现同时监视多个输入属性值的变化。

在子组件DemoChildComponent新增ngOnChanges:

rush:js;"> @Component({ selector: 'demo-child',template: `

{{paramOneVal}}

{{paramTwo}}

` }) export class DemoChildComponent implements OnChanges { private paramOneVal: any;

@input()
set paramOne (val: any) { // 输入属性1
this.paramOneVal = val;
// dosomething
};
get paramOne () {
return this.paramOneVal;
};

@input() paramTwo: any; // 输入属性2

ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
for (let propName in changes) { // 遍历changes
let changedProp = changes[propName]; // propName是输入属性的变量名称
let to = JSON.stringify(changedProp.currentValue); // 获取输入属性当前值
if (changedProp.isFirstChange()) { // 判断输入属性是否首次变化
console.log(Initial value of ${propName} set to ${to});
} else {
let from = JSON.stringify(changedProp.prevIoUsValue); // 获取输入属性先前值
console.log(${propName} changed from ${from} to ${to});
}
}
}
}

新增的ngOnChanges方法接收的参数changes是以输入属性名称为键、值为SimpleChange的对象,SimpleChange对象含有当前输入属性是否第一次变化、先前值、当前值等属性。因此在ngOnChanges方法中通过遍历changes对象可监视多个输入属性值并进行相应的操作。

获取父组件实例

前面介绍的都是子组件通过@Input装饰器定义输入属性,这样父组件可通过输入属性将数据传递给子组件。

当然,我们可以想到一种更主动的方法,那就是获取到父组件实例,然后调用父组件的某个属性或方法来获取需要的数据。考虑到每个组件的实例都会添加到注入器的容器里,因此可通过依赖注入来找到父组件的示例。

子组件获取父组件实例相比于父组件获取子组件实例(直接通过模板变量、@ViewChild或@ViewChildren获取)要麻烦一些。

要在子组件中获取父组件的实例,有两种情况:

已知父组件的类型

这种情况可以直接通过在构造函数中注入DemoParentComponent来获取已知类型的父组件引用,代码示例如下:

rush:js;"> @Component({ selector: 'demo-child',template: `

{{paramOne}}

{{paramTwo}}

` }) export class DemoChildComponent { paramOne: any; paramTwo: any;

constructor(public demoParent: DemoParentComponent) {

// 通过父组件实例demoParent获取数据
this.paramOne = demoParent.paramOneVal;
this.paramTwo = demoParent.paramTwoval;
}
}

未知父组件的类型

一个组件可能是多个组件的子组件,有时候无法直接知道父组件的类型,在Angular中,可通过类—接口(Class-Interface)的方式来查找,即让父组件通过提供一个与类—接口标识同名的别名来协助查找。

首先创建DemoParent抽象类,它只声明了paramOneVal和paramTwoval属性,没有实现(赋值),示例代码如下:

rush:js;"> export abstract class DemoParent { paramOneVal: any; paramTwoval: any; }

然后在父组件DemoParentComponent的providers元数据中定义一个别名 Provider,用 useExisting 来注入父组件DemoParentComponent的实例,代码示例如下:

rush:js;"> @Component({ selector: 'demo-parent',template: ` `,providers: [{provider: DemoParent,useExisting: DemoParentComponent}] }) export class DemoParentComponent implements DemoParent { paramOneVal: any = '传递给paramOne的数据'; paramTwoval: any = '传递给paramTwo的数据'; }

然后在子组件中就可通过DemoParent这个标识找到父组件的示例了,示例代码如下:

rush:js;"> @Component({ selector: 'demo-child',template: `

{{paramOne}}

{{paramTwo}}

` }) export class DemoChildComponent { paramOne: any; paramTwo: any;

constructor(public demoParent: DemoParent) {

// 通过父组件实例demoParent获取数据
this.paramOne = demoParent.paramOneVal;
this.paramTwo = demoParent.paramTwoval;
}
}

子组件向父组件传递

依然先定义两个组件,分别为子组件DemoChildComponent和父组件DemoParentComponent.

子组件:

rush:js;"> @Component({ selector: 'demo-child',template: `

子组件DemoChildComponent

` }) export class DemoChildComponent implements OnInit { readyInfo: string = '子组件DemoChildComponent初始化完成!'; @Output() ready: EventEmitter = new EventEmitter(); // 输出属性

ngOnInit() {
this.ready.emit(this.readyInfo);
}
}

父组件:

rush:js;"> @Component({ selector: 'demo-parent',template: `

readyInfo: {{demoChild.readyInfo}}

readyInfo: {{demoChildComponent.readyInfo}}

` }) export class DemoParentComponent implements AfterViewInit { // @ViewChild('demoChild') demoChildComponent: DemoChildComponent; // 通过模板别名获取 @ViewChild(DemoChildComponent) demoChildComponent: DemoChildComponent; // 通过组件类型获取

ngAfterViewInit() {
console.log(this.demoChildComponent.readyInfo); // 打印结果:子组件DemoChildComponent初始化完成!
}

onReady(evt: any) {
console.log(evt); // 打印结果:子组件DemoChildComponent初始化完成!
}
}

父组件监听子组件的事件

子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

在上面定义好的子组件和父组件,我们可以看到:

子组件通过@Output()定义输出属性ready,然后在ngOnInit中利用ready属性的 emits(向上弹射)事件。

父组件在其模板中通过选择器demo-child引用子组件DemoChildComponent,并绑定了一个事件处理器(onReady()),用来响应子组件的事件($event)并打印出数据(onReady($event)中的$event是固定写法,框架(Angular)把事件参数(用 $event 表示)传给事件处理方法)。

父组件与子组件通过本地变量(模板变量)互动

父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法。

在上面定义好的子组件和父组件,我们可以看到:

父组件在模板demo-child标签上定义了一个demoChild本地变量,然后在模板中获取子组件的属性:

rush:xhtml;">

readyInfo: {{demoChild.readyInfo}}

父组件调用@ViewChild()

本地变量方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。

如果父组件的类需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法。

当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。

在上面定义好的子组件和父组件,我们可以看到:

父组件在组件类中通过@ViewChild()获取到子组件的实例,然后就可以在模板或者组件类中通过该实例获取子组件的属性:

rush:xhtml;">

readyInfo: {{demoChildComponent.readyInfo}}

rush:js;"> ngAfterViewInit() { console.log(this.demoChildComponent.readyInfo); // 打印结果:子组件DemoChildComponent初始化完成! }

通过服务传递

Angular的服务可以在模块注入或者组件注入(均通过providers注入)。

在模块中注入的服务在整个Angular应用都可以访问(除惰性加载的模块)。

在组件中注入的服务就只能该组件和其子组件进行访问,这个组件子树之外的组件将无法访问该服务或者与它们通讯。

下面的示例就以在组件中注入的服务来进行父子组件之间的数据传递:

通讯的服务:

rush:js;"> @Injectable() export class CallService { info: string = '我是CallService的info'; }

父组件:

rush:js;"> @Component({ selector: 'demo-parent',template: `

子组件:

rush:js;"> @Component({ selector: 'demo-child',template: `

上面的代码中,我们定义了一个CallService服务,在其内定义了info属性,后面将分别在父子组件通过修改这个属性的值达到父子组件互相传递数据的目的。

然后通过DemoParentComponent的providers元数据数组提供CallService服务的实例,并通过构造函数分别注入到父子组件中。

此时,通过父组件改变info按钮或子组件改变info按钮在父组件或子组件中改变CallService服务的info属性值,然后在页面可看到改变之后对应的info属性值。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。

Angular 组件之间的传值

Angular 组件之间的传值

第一种方法(传单个或者多个参数):

主页面方法:

先添加引用:private _routes: Router,

Details(PBSCode) {
this._routes.navigate([''pbs-manage/pbs-detail'', PBSCode]);
}
路由:
//  reuse: true 可以使本页面不关闭
{
path: ''pbs-detail/:PBSCode'',
component: PBSDetailComponent,
data: { title: ''详情'', reuse: true }
}
子页面接收:
ngOnInit() {
this.route.queryParams.subscribe((e) => {
this.PBSCode= e.get(''PBSCode'');
});
}
缺点:该方法会把参数显示在地址栏上
第二个方法(传对象):
主页面: private _routes: Router,
添加引用:
Details(bb,cc) {
this.router.navigate([''/workOrder-manage/challenge-list''], { queryParams: { aa: bb, cc: dd } });
}
子页面:
ngOnInit() {
this.route.queryParams.subscribe((e) => {
this.aa= e.aa;
this.cc = e.cc ;
});
}
备注:该方式与第一个方法的缺点一致,好处是不用配置路由
第三种方式(模态窗)
// 补充信息
主页面方法:
// componentParams中的是传的值 content是子页面的名字
EditCarrier(ContractID) {
const options = {
wrapClassName: ''modal-lg custom-modal'',
content: PublicContractEditCarrierComponent,
footer: false,
componentParams: {
ContractID: ContractID
}
};
// 子页面关闭触发的事件
this.modal.open(options).subscribe(result => {
if (result === ''onDestroy'') {
this.GetDatas(0);
}
});
}
子页面接收:
@Input()
set dataci(ci: number) {
this.ContractID = ci;
}
备注:主页面的传值参数名与子页面接收的参数名必须一致
第四中:
主页面:
html:
//子页面的组件名字 
<app-back-admin-assessment-early-warning-index (receive)="GetParameters($event)"></app-back-admin-assessment-early-warning-index>
ts页面:
GetParameters(e) {
console.log(e);
}
子页面:
// receive这个名字随意 但主页的触发方法的名字要与这里的名字一致
@Output(''receive'') checkedBack = new EventEmitter<any>();
//触发这个方法就可以传值到主页面
this.checkedBack.emit(this.params);

angular1.5 组件学习 -- 2.1、组件间的交互:父向子

angular1.5 组件学习 -- 2.1、组件间的交互:父向子

一个组件干一个事,一个完整的功能有时需要多个组件协调完成,这就少不了组件间的数据交互,那先来记录下父组件向子组件传递数据。

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>父组件向子组件传递变量</title>
    <script src="angular.js"></script>
</head>

<body>
    <father-component></father-component>
    <script>
        angular.module(''myApp'',[])
            .component(''fatherComponent'', {
                template: "<h3>father-component <input ng-model=''$ctrl.sayHello''></h3>" + 
                "<child-component say-some=''$ctrl.sayHello''></child-component>",
                controller: function () {
                    this.sayHello = ''Hello'';
                }
            })
            .component(''childComponent'', {
                template: "<h3>child-component <input ng-model=''$ctrl.saySome''></h3>",
                controller: function () {
                    this.$onChanges = function (event) {
                        console.log(event);
                    }
                },
                bindings: {
                    saySome: "<"
                }
            })
    </script>
</body>
</html>

类似于调用指令时与指令的数据传递:将要绑定的变量写在调用的子组件自定义元素标签上,然后子组件通过 bindings 属性设置绑定的变量名(此名称为子组件作用域内供调用的变量名称)。

绑定的属性有三种前缀标识符可设置:

  1、“@”,单项绑定的前缀标识符,用于传递字符串;

  2、“=”,双向绑定标识符,父组件与子组件的变量的变化会相互影响;

  此基础上 compnent 还增加了一种标识符:

  3、“<”,单项数据传输,父组件状态的改变会传给子组件,子组件状态改变不会影响父组件状态。组件中建议使用此标识符,可触发生命周期钩子:$onChanges(changesObj)。

今天关于Angular4学习笔记——组件之间的交互angular组件之间通信的讲解已经结束,谢谢您的阅读,如果想了解更多关于Angular 8 学习 (七 进阶) 组件之间的传值问题、Angular 组件之间的交互的示例代码、Angular 组件之间的传值、angular1.5 组件学习 -- 2.1、组件间的交互:父向子的相关知识,请在本站搜索。

本文标签: