在项目中遇到了这样一个问题,父页面中需要操作子组件里面的方法,这个时候需要怎么做呢?项目是由ionic3.0和angular4.0构成的 代码如下:
child的html页面如下:
<div class="child" [class.actived]="hideBtn">
<div *ngIf="childImage" class="child-image"><img src="assets/child/{{childImage}}"></div>
<div *ngIf= "hideBtn" (click)="hideChild()" class="hide-btn"></div>
<div *ngIf= "showBtn" (click)="showChild()" class="show-btn"></div>
</div>
ts页面如下:
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { NavController, NavParams, ModalController } from "ionic-angular";
import { Config } from "providers/config";
import { User } from "providers/user";
import { Api } from "providers/api";
import { Funcs } from "providers/funcs";
@Component({
selector: 'child',
templateUrl: "child.html",
})
export class child {
hideBtn: boolean = false;
showBtn: boolean = true;
constructor(
public config: Config,
public navCtrl: NavController,
public navParams: NavParams,
public modalCtrl: ModalController,
public user: User,
public api: Api,
public funcs: Funcs,
) {
}
@Input() childImage:string = '';
@Output() showFlag = new EventEmitter();
ionViewDidEnter() {}
showGuide(){
this.showBtn = false
this.hideBtn = true
this.showFlag.emit(true)
}
hideGuide(){
this.showBtn = true
this.hideBtn = false
this.showFlag.emit(false)
}
}
上面是子组件里面的html和ts。
首先子组件接收参数是通过@Input() childImage:string = ‘’;
@Input() 是用来定义输入的,是接收其他组件传过来的数据的。相当于指令的值绑定,无论是单向的(@)还是双向的(=)。都是将父作用域的值“输入”到子作用域中,然后子作用域进行相关处理。(相当于vue中的props)
然后子组件抛出方法是通过@Output() showFlag = new EventEmitter();
@output相当于指令的方法绑定,子作用域触发事件执行响应函数,而响应函数方法体则位于父作用域中,相当于将事件“输出到”父作用域中,在父作用域中处理。(相当于vue中的emit 实现通信)
(可以结合之前我之前写的这篇文章对比记忆:vue中的父子组件之间的数据传递之props、
r
e
f
和
ref和
ref和emit)
那下面让我们来看一下父组件中的代码吧
parent的html页面如下(引用子组件的部分):
<div [hidden]="toggleClass != 'unShow'">
<child #childMask1 [childImage]="'unShowContGuide.png'" (showFlag)="showFlag($event)" class="childCom"></child>
</div>
<div [hidden]="toggleClass != 'isShow'">
<guide #childMask2 [childImage]="'isShowContGuide.png'" (showFlag)="showFlag($event)" class="childCom"></guide>
</div>
<div *ngIf="childMask" [hidden]="toggleSignClass != 'unShow'" (click)="childMask1.hideGuide()" class="mask"></div>
<div *ngIf="childMask" [hidden]="toggleSignClass != 'isShow'" (click)="childMask2.hideGuide()" class="mask"></div>
ts页面如下(引用子组件的部分):
import { Component, ViewChild } from "@angular/core";
import { child } from "../child/child";
export class parent {
@ViewChild("childMask1") childMask1: child;
@ViewChild("childMask2") childMask2: child;
showMask: boolean = false;
constructor(
) {
}
ionViewDidEnter() {
this.childMask1.showGuide();
this.childMask2.showGuide();
}
// 子组件的点击事件
showFlag(event) {
this.childMask = event;
}
}
通过父组件页面我们可以看到,在父组件里面引入子组件的方法就是直接以子组件中定好的选择器为标签
@Component({
selector: ‘child’,
templateUrl: “child.html”,
})
<child #childMask1 [childImage]="‘unShowContGuide.png’" (showFlag)=“showFlag($event)” class=“childCom”></child>
在标签中直接定义一个类似于id的#childMask1,这个childMask1就可以在父组件的其他标签中随意使用了,
<div *ngIf="childMask" [hidden]="toggleSignClass != 'unShow'" (click)="childMask1.hideGuide()" class="mask"></div>
这个标签中的childMask1就是之前定义好的类似于id的#childMask1。
那么我们回到最开始的那个问题:我刚进入父组件页面的时候就去调用子组件里面的方法
@ViewChild(“childMask1”) childMask1: child;
@ViewChild(“childMask2”) childMask2: child;
这两行代码就是关键,意思是把childMask1和childMask2定义为子组件child类的数据类型,然后我就可以用
childMask1和childMask2直接调用子组件里面的方法和属性了(这个类似于vue中的$ref)
angular和vue中的父子组件之间的传递的原理都是一样的,只是方法和写法不一样,大家可以对比去记忆。
好了,就到这里吧,以后有什么新的发现再补充。