Angular8组件通信基本使用场景(一)
时间:2023-04-05 01:57:10
HTML5
组件交互父子组件交互(常用)输入输出属性Input,最基本的输出场景之一,应用广泛。使用方法将父组件中的数据绑定到子组件声明的变量上,保证子组件可以用于内部渲染模板。主要关注子组件的内部代码格式:import{Component,OnInit,Input}from'@angular/core';@Component({selector:'app-children',templateUrl:'./children.component.html',styleUrls:['./children.component.scss']})exportclassChildrenComponentimplementsOnInit{@Input()List:Array;constructor(){}ngOnInit(){}}通过@Input装饰器将此变量声明为输入属性,用于像dom一样绑定属性,但有区别:当前总记录数:{{dataList.length}}使用[]符号绑定当前组件或页面中的数据。这种场景数据传输方向比较单一简单。在实际开发中,更多的子组件也会对部分数据进行操作,父组件也必须时刻接收变化。在Angular中,子组件传播事件需要从@angular/core引入EventEmitter类。demo如下://组件中的代码@Output()removeHandler=newEventEmitter();//组件模板中的操作事件removeAll(){this.List=[];this.removeHandler.emit(dataoreventname);}模板:子组件显示表格:
姓名 | 电话 |
---|
{{item.name}} | {{item.phone}} | td>
父组件:removeData(e){console.log(e);这个.dataList=e;//如何根据场景更新数据到这个组件实现}onChanges生命周期拦截input属性变化。另外,官方demo还提供了两种拦截输入值变化的方式来更新本地数据。一种是对子组件绑定的属性进行getter和setter处理;另一种在开发中使用较多,使用组件的声明循环钩子ngOnChanges函数进行处理。我将修改上面的demo,子组件:exportclassChildrenComponentimplementtsOnInit,OnChanges{@Input()List:Array;}变更列表=[];@Output()removeHandler=newEventEmitter();constructor(){}ngOnInit(){}ngOnChanges(changes:{[propKey:string]:SimpleChange}){让日志=[];如果(!changes.List.firstChange){logs=changes.List.currentValue;this.changeList=日志;}}removeAll(){this.changeList=[];this.removeHandler.emit(this.changeList);}}姓名 | 电话 |
---|
{{item.name}} | {{item.phone}} |
<按钮(点击)="removeAll()">ClearAll请注意,在本例中,我只绑定了一个输入属性。如果有多个,则应使用for循环更新指定数据。局部变量Interactive官方定义:父组件不能使用数据绑定来读取子组件的属性或调用方法。但是在父组件模板中,新建一个局部变量来表示子组件,然后通过这个变量读取子组件的属性,调用子组件的方法来修改子组件;导出类ChildrenComponent实现OnInit{//@Input()List:Array;变更列表=[];//@Output()removeHandler=newEventEmitter();constructor(){}ngOnInit(){}addData(data){this.changeList=[...this.变更列表,数据];}removeAll(){this.changeList=[];}}html模板不变;父组件:添加一条新记录
当前记录总数:{{table.changeList.length}}
exportclassBasicComponentimplementsOnInit{constructor(){}name='';电话='';ngOnInit(){}}删除组件中的逻辑,因为绑定的#table可以直接访问子组件的属性和方法父组件调用@ViewChild有时我们需要在组件中直接访问子组件中的属性和方法,局部变量是不适用的。可以考虑使用@ViewChild()修改父组件:
添加新记录
> 当前记录总数:{{dataList.length}}
import{Component,OnInit,ViewChild}from'@angular/core';import{ChildrenComponent}from'../children/children.component';@Component({selector:'app-basic',templateUrl:'./basic.component.html',styleUrls:['./basic.component.scss']})exportclassBasicComponentimplementsOnInit{@ViewChild(ChildrenComponent,{static:false})私人孩子:儿童组件;构造函数(){}名称='';电话='';数据列表=[];ngOnInit(){}addData(){this.dataList=[...this.dataList,{name:this.name,phone:this.phone}];this.children.addData({name:this.name,phone:this.phone});}removeAll(){this.dataList=[];this.children.removeAll();}}如果子组件中有初始化操作,可以在父组件的AfterViewInit语句循环中初始化。任何组件之间的服务间(Service)业务中有很多交互,往往没有父子组件的关系。这时候使用服务交互是一个不错的选择。服务文件代码:import{Injectable}from'@angular/core';import{Subject}from'rxjs';@Injectable({providedIn:'root'})exportclassWorkerListService{workList=[];workListSource=newSubject<任何>();私有workListSource$=this.workListSource.asObservable();constructor(){}addInfo(info){this.workList=[...this.workList,info];this.workListSource.next(this.workList);}updateWorkList(infos:Array
){this.workList=infos;this.workListSource.next(this.workList);}}解释代码部分。首先,一个数据可以被订阅的前提必须是一个Observable类型,因为(SomeArray)的普通数组已经是一个可以被订阅的Observable类型,对于返回的http请求也是一个Observable类型,可以是直接在页面上订阅和处理。Ng官方文档中有列出Observable类型的说明。想了解更多,可以去查看,next()方法告诉可观察对象更新内容,这样你的订阅(subscribe)就会抓取更新的信息。原父组件:import{Component,OnInit}from'@angular/core';import{WorkerListService}from'../worker-list.service';@Component({selector:'app-basic',templateUrl:'./basic.component.html',styleUrls:['./basic.component.scss']})exportclassBasicComponentimplementsOnInit{constructor(privateworkListService:WorkerListService){}name='';电话='';数据列表=[];ngOnInit(){this.workListService.workListSource.subscribe(res=>{this.dataList=res;});}addData(){this.workListService.addInfo({name:this.name,phone:this.phone});}removeAll(){this.dataList=[];this.workListService.updateWorkList(this.dataList);}}原始组件:import{Component,OnInit}from'@angular/core';import{WorkerListService}from'../worker-list.service';@Component({selector:'app-children',templateUrl:'./children.component.html',styleUrls:['./children.component.scss']})导出类ChildrenComponent实现OnInit{changeList=[];constructor(privateworkListService:WorkerListService){this.workListService.workListSource.subscribe(res=>{this.changeList=res;});}ngOnInit(){}}这样组件就可以随时获取最新的数据更新而不用担心是不是父子组件,这也是最常用的方法