繁体   English   中英

触发子组件的ngOnInit angular

[英]triggering ngOnInit of children components angular

我有一个父组件和几个子组件显示为标签。 我无法控制孩子 ngOnInit 的行为,因为当从一个 label 更改为另一个时,孩子的 ngOnInit 不会触发。

父亲是应用管理,它的 html 是:

 <mat-tab-group dynamicHeight="true">
      <mat-tab label="Application Loader">
        <app-loader [deviceId]="deviceId"></app-loader>
      </mat-tab>
      <mat-tab label="Application Config">
        <app-config [deviceId]="deviceId"></app-config>
      </mat-tab>
      <mat-tab label="Docker">
        <app-docker [deviceId]="deviceId"></app-docker>
      </mat-tab>
      <mat-tab label="Application Logs">
        <app-logs [deviceId]="deviceId"></app-logs>
      </mat-tab>
      <mat-tab label="Ack Logs">
        <exec-logs [deviceId]="deviceId"></exec-logs>
      </mat-tab>
      <mat-tab label="Docker Logs">
        <docker-logs [deviceId]="deviceId"></docker-logs>
      </mat-tab>
    </mat-tab-group>

在 app-docker 的 ngOnint 中引入 console.log 时不起作用。 我需要从 app-loader 中的事件在 app-docker 中实现订阅,因为当应用程序更改时,该更改显示在 app-docker 中,但是,由于导航到 label 时不会触发 ngOninit,我不知道如何解决这个问题。

VC中的结构是aa如下:

>app-config
>app-docker
>app-loader
>app-logs
>docker-logs
>exec-logs
app-management.component.html
app-management.component.scss
app-management.component.ts
app-management.service.ts

我试过这个:在我的 app-docker.ts


import { Component, OnInit, Input, ChangeDetectorRef } from '@angular/core';
import { AppManagementService } from "../app-management.service";
import { SnackMessageService } from "app/main/common/services/snackMessage.service";
import { Subscription } from 'rxjs';


@Component({
  selector: "app-docker",
  templateUrl: "./app-docker.component.html",
  styleUrls: ["./app-docker.component.scss"],
})
export class AppDockerComponent implements OnInit {
  @Input() deviceId: string;
  configErrorMessage: string;
  
  dataContainer: any;
  
  application: any;
  private appChangeSub: Subscription;


  constructor(
    private appManagementService: AppManagementService,
    private snackMessageService: SnackMessageService, private cd: ChangeDetectorRef) {

 
      this.dataContainer = {
        containerInfo: [],
        dockerInfo: [],
        timestamp: ""  
    }

  

    this.application = {
      lastUpdate: new Date(0),
      registryId: "",
      applicationId: ""
  }
  }

  ngOnInit() {
      this.appManagementService.getDevicepplication(this.deviceId).then(response => {
        this.application = response
        if (this.application.applicationId !== "") {
          this.postContainerInfo();
        }
        this.appChangeSub = this.appManagementService.onSelectedApplicationsChanged.subscribe(app => {
          this.application.applicationId = app
        })
      }).catch(()=>  this.configErrorMessage = "Oops, could not get application info")

  }

public postContainerInfo() {
    this.appManagementService.postContainerInfo(this.deviceId).then(() => { this.getDockerContainerInfo() }).catch(() => this.configErrorMessage = "Oops, could not send container info message.")
  }

public getDockerContainerInfo() {
    this.appManagementService.getDockerContainerInfo(this.deviceId).then(response => {
      this.dataContainer = response
    }).catch(() => this.configErrorMessage = "Oops, could not get docker data.");
  }

app-loader 加载一个新的应用程序,每次这个应用程序更改时,我需要在转到 app-docker label 时显示这些更改,而无需按任何按钮。 那可能吗?

我的应用程序加载器 component.ts

import { Component, OnInit, Input, OnDestroy } from "@angular/core";
import { FormGroup, FormBuilder, Validators } from "@angular/forms";
import { RegistryModel } from "app/main/registry/registry.model";
import { ApplicationModel } from "app/main/registry/application.model";
import { AppManagementService } from "../app-management.service";
import { SnackMessageService } from "app/main/common/services/snackMessage.service";

import { MatDialogRef, MatDialog } from "@angular/material";
import { FuseConfirmDialogComponent } from "@fuse/components/confirm-dialog/confirm-dialog.component";


@Component({
  selector: "app-loader",
  templateUrl: "./app-loader.component.html",
  styleUrls: ["./app-loader.component.scss"]
})
export class AppLoaderComponent implements OnInit, OnDestroy {
  @Input() deviceId: string;

 ngOnInit() {}

 public sendRegistryForm(): void {
    this.confirmDialogRef = this.matDialog.open(FuseConfirmDialogComponent, {
      disableClose: false
    });

    this.confirmDialogRef.componentInstance.confirmMessage = "Are you sure you want to send this application to the device?";

    this.confirmDialogRef.afterClosed()
      .subscribe(result => {
        if (result) {
          this.appManagementService.sendApplicationToDevice(this.deviceId, this.registryForm.value.registryId, this.registryForm.value.applicationId).then(() => {
            this.loaderErrorMessage = null;
            this.snackMessageService.sendMessage("Application sent");
          }).catch(() => this.loaderErrorMessage = "Oops, could not send the application to the device.");

        }
        this.confirmDialogRef = null;
      });
  }

}

在 appmanagementservice 中,每次加载新应用程序时,我都尝试使用 next 实现发射器,但是,我不确定这是否正确。 app-docker 中的 postContainerInfo 方法是向 mqtt 服务发送消息,更新 ddbb,然后通过 getContainerInfo() 获取更新的信息。

我的 app-management.service.ts:

import { Injectable } from "@angular/core";
import { RegistryModel } from "app/main/registry/registry.model";
import { BackEndCommunicationService } from "app/main/common/services/beComm.service";
import { BehaviorSubject, Subject } from "rxjs";

@Injectable({
  providedIn: "root"
})
export class AppManagementService {
  onSelectedApplicationsChanged: Subject<any>;

  constructor(private backEndCommunicationService: BackEndCommunicationService) {
    this.onSelectedApplicationsChanged = new Subject();
   }

 public getDevicepplication(deviceId: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.backEndCommunicationService.getResource("/devices/" + deviceId).then((response: any) => {
        this.onSelectedApplicationsChanged.next()
        resolve(response.response.application);
      }).catch(error => {
        console.log(error);
        reject("Error getting persistant size")
      })
    })
  }

public sendApplicationToDevice(deviceId: string, registryId: string, applicationId: string): Promise<void> {
    return new Promise((resolve, reject) => {
      const sendObject = {
        data: {
          registryId: registryId,
          applicationId: applicationId
        }
      };
      this.backEndCommunicationService.postResource("/devices/" + deviceId + "/application", sendObject).then(() => {
        resolve();
      }).catch(error => {
        console.log(error);
        reject("Error sending app to device");
      });
    });
  }

ngOnInit不会运行,因为 DOM:选项卡标签和内容是构建一次,而不是在每次单击时重新构建。

您可以使用selectedTabChange事件对选项卡更改做出反应。 你到底想达到什么目的?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM