简体   繁体   English

触发子组件的ngOnInit angular

[英]triggering ngOnInit of children components angular

I have a father component and several child components displayed as labels.我有一个父组件和几个子组件显示为标签。 I'm having trouble to control the behavior of the children ngOnInit as when changing from one label to another, ngOnInit of children won't trigger.我无法控制孩子 ngOnInit 的行为,因为当从一个 label 更改为另一个时,孩子的 ngOnInit 不会触发。

The father is app-management and its html is:父亲是应用管理,它的 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>

When introducing a console.log in ngOnint of app-docker doesn't work.在 app-docker 的 ngOnint 中引入 console.log 时不起作用。 I need to implemement a subscription in app-docker from the event in app-loader as when the application changes that change is displayed in app-docker, but, as ngOninit won't trigger when navigating to that label, I have no idea how to solve this.我需要从 app-loader 中的事件在 app-docker 中实现订阅,因为当应用程序更改时,该更改显示在 app-docker 中,但是,由于导航到 label 时不会触发 ngOninit,我不知道如何解决这个问题。

The structure in VC it's aa follows: 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

I have tried this: on my app-docker.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.");
  }

the app-loader loads a new application, and every time this application changes I need to display these changes when going to app-docker label, without pressing any button. app-loader 加载一个新的应用程序,每次这个应用程序更改时,我需要在转到 app-docker label 时显示这些更改,而无需按任何按钮。 Is that possible?那可能吗?

my app-loader component.ts我的应用程序加载器 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;
      });
  }

}

In the appmanagementservice, I'm trying to implement an emitter with next each time a new application is loaded, but, I'm not sure this is right.在 appmanagementservice 中,每次加载新应用程序时,我都尝试使用 next 实现发射器,但是,我不确定这是否正确。 The method postContainerInfo in app-docker is sending a message to an mqtt service, updating a ddbb, and then getting the info updated through getContainerInfo(). app-docker 中的 postContainerInfo 方法是向 mqtt 服务发送消息,更新 ddbb,然后通过 getContainerInfo() 获取更新的信息。

My app-management.service.ts:我的 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");
      });
    });
  }

The ngOnInit won't run, because the DOM: the tab labels and the content, is built once, not rebuilt on every click. ngOnInit不会运行,因为 DOM:选项卡标签和内容是构建一次,而不是在每次单击时重新构建。

You can use the selectedTabChange event to react to the tab change.您可以使用selectedTabChange事件对选项卡更改做出反应。 What exactly are you trying to achieve?你到底想达到什么目的?

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

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