简体   繁体   中英

Change variable value from different component - Angular 4

I have two components, one is the home.component, and one is loading.component (loading screen). The loading screen has a countdown, and after the countdown, he does something. What I need to do is make the loading screen capable of custom countdown length. I tried using the EventEmiter, but it doesn't work.

home.component.html:

<a (click)="applyChanges()" class="green" style="margin-left: 8px; cursor: pointer"><i style="margin-right: 5px;"class="fa fa-check"></i>Apply changes now</a>

home.component.ts

@Output() loadingScreenStart: EventEmitter<any> = new EventEmitter();


applyChanges(){
this.dashboard.applyChanges().catch(
  err => {
    console.log("There was an error: "+err.status);
    console.log("There was an error: "+err.statusText);
    //this.handleError(err);
    return Observable.throw(err);
  }
)
.subscribe(
  data => {
    this.loadingScreenStart.emit(34);
    this.router.navigate(['/loading']);
  }
);

} loading.component.html

<div class="container container-table" (loadingScreenStarted)="onScreenStart($event)">
  <div class="row vertical-10p">
    <div class="container">
      <img src="../../assets/img/LoginLogo.png" class="center-block logo">
      <img style="width: 15em"  src="../../assets/img/gears.svg" class="center-block ">
      <div class="text-center col-sm-6 col-sm-offset-3">
        <h1>Changes are taking place</h1>
        <h4>You will be redirected in {{timeLeft}} seconds</h4>
      </div>
    </div>
  </div>

loading.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { AuthGuard } from '../guard/auth.guard';
import { Title } from '@angular/platform-browser';
@Component({
  selector: 'app-loading',
  templateUrl: './loading.component.html',
  styleUrls: ['./loading.component.css']
})
export class LoadingComponent implements OnInit {
   public timeLeft;
   public intervalId;
   constructor(public titleService: Title, public guard: AuthGuard) { }
   onScreenStart(length) {
      this.timeLeft = length;
      console.log(length);
   }
   ngOnInit() {
      this.titleService.setTitle("Loading... | something);
      this.startCounter();
      localStorage.removeItem('statusInfo');
   }
   startCounter() {
      this.intervalId = setInterval(() => {
         if (this.timeLeft == 1) {
            clearInterval(this.interValId);
         }
         this.timeLeft--;
      }, 1000)
   }
}

There are 2 things wrong in you code.

  1. Understand how EventEmitter works.

When you are emitting a value from child using eventEmitter, you will need to map it to some method of the parent component.

// in child component.
    @Output()
    myEmitter   = new EventEmitter();

    someMethod() {
     this.myemitter.emit('somevalue');
}

Now it actually receive this value of emitter you need to map this to a method of parent compoenent.

  someParentMethod(value) {
      console.log(value);
  }

<app-child (myEmitter)="someParentMethod(event)"></app-child>

2. Observable's error handling. Since you are throw an Observable, you will need to handle it in the subscribe. Observable's subscribe consist of 3 parts. Response , ErrorHandling , Next . Now, you are throwing an error from Observable.throw, your res part will not run. But you are not handling error, so you won't see anything. Instead do this:

.subscribe(
  data => {
    this.loadingScreenStart.emit(34);
    this.router.navigate(['/loading']);
  },
  error => console.log(error)
);

Since these two components are not in a parent/child relationship, I don't think that you're going to be able to successfully use an EventEmitter. The major problem is that you can't depend on both components being in existence at the same time.

So, the two common choices for your situation are:

  1. pass the data in a route parameter (example at https://angular.io/tutorial/toh-pt5#navigating-to-hero-details )

  2. communicate through a shared service (example at https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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