首页 > 解决方案 > 从另一个孩子Angular调用一个孩子的功能

问题描述

我想从另一个组件调用子组件具有的方法,该组件是同一父级的子级但处于较低级别。示意图:

            |--Child B
 Father A---|
            |--Child C---|--Child D   

A是每个人的父亲,它有两个孩子,B和C。C也是D的父亲。

在我的 Angular 应用程序中,组件 B 有一个地图实例和管理该地图的函数。C 是一个路由器组件,它根据应用程序更改 D 组件。

组分 A

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {

}

组件 A 的 HTML

<ng-container>
   <mat-sidenav-container> 
      <mat-sidenav>
         <!--Component C-->
          <router-outlet></router-outlet>
      </mat-sidenav>
      <mat-sidenav-content >
        <!--Component B-->
        <app-map></app-map>
      </mat-sidenav-content>
   </mat-sidenav-container>
</ng-container>

B组份

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})


    export class MapComponent implements OnInit {
      ngOnInit(){...}
      drawWMSLayer(layerName:string){...}
      deleteWMSLayer(){...}
      drawCoordinates(coordinates:any){...}
      obtainIDENAMap(){...}
      //......//
    }

组件 B 的 HTML

<div id="map" class="map"></div> <!--Openlayers map-->

组分 C

const routes: Routes = [
  { path: '', redirectTo: '/inicio', pathMatch: 'full' },
  { path: 'inicio', component: PaginaInicioComponent },
  { path: 'edificios', component: EdificiosComponent },
  { path: 'parkings', component: ParkingsComponent },
  //..........//
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

组件 D 被路由器更改(其中之一)

@Component({
  selector: 'app-edificios',
  templateUrl: './edificios.component.html',
  styleUrls: ['./edificios.component.css']
})
export class EdificiosComponent implements OnInit {
  //........//
 /* I would like to call MapComponent functions from here */
}

组件 B 总是一样的,它只是通过它的函数来修改它的属性值。

它是一个“谷歌地图类型”应用程序,其中地图是相同的,它会根据您调用的功能改变其外观。

标签: angular

解决方案


由于这是遵循不同的层次结构,并且事物也可以进一步嵌套,我建议使用服务来处理这些案例。

class MyMapService {
  methodCallSource = new BehaviorSubject<{method: string, params: any}>(null);
  methodCall$: Observable<{method: string, params: any}>;

  constructor() {
    this.methodCall$ = this.methodCallSource.asObservable();
  }
}
class ComponentB {
  mapMethodCallSub;
  constructor () {
    private myMapService: MyMapService
  }

  ngOnInit() {
    this.mapMethodCallSub = this.myMapService.methodCall$
      .subscribe((callArgs) => {
        const {method, params} = callArgs;
        switch(method) {
          case 'doSomething':
            this.doSomething(params);
            break;
          case 'doSomethingElse':
            this.doSomething(params);
            break;
        }
      })
  }

  ngOnDestroy() {
    this.mapMethodCallSub.unsubscribe();
  }
  doSomething({param1}) { // keep your params as objects

  }
  doSomethingElse({param1, param2}) { // keep your params as objects

  }
}
class ComponentD {
  constructor () {
    private myMapService: MyMapService
  }

  someTrigger() {
    this.myMapService.methodCallSource.next('doSomething', {param1: 'Ahsan'});
  }

  someActionTest() {
    this.myMapService.methodCallSource.next('doSomethingElse', {param1: 'Satellite', param2: 'Texas'});
  }
}

推荐阅读