Изменить значение переменной из другого компонента - Angular 4 - PullRequest
0 голосов
/ 28 мая 2018

У меня есть два компонента, один - home.component, а другой - loading.component (экран загрузки).На экране загрузки есть обратный отсчет, и после обратного отсчета он что-то делает.Что мне нужно сделать, это сделать экран загрузки способным к произвольной длине обратного отсчета.Я пытался использовать EventEmiter, но он не работает.

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']);
  }
);

} загрузка.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)
   }
}

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Поскольку эти два компонента не находятся в отношениях родитель / потомок, я не думаю, что вы сможете успешно использовать EventEmitter.Основная проблема заключается в том, что вы не можете зависеть от того, что оба компонента существуют одновременно.

Итак, в вашей ситуации есть два варианта:

  1. передать данные в параметре маршрута (например, https://angular.io/tutorial/toh-pt5#navigating-to-hero-details)

  2. обмениваться данными через общую службу (например, https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service)

0 голосов
/ 28 мая 2018

В вашем коде есть 2 неправильные вещи.

  1. Понять, как работает EventEmitter.

Когда вы отправляете значение из дочернего элемента с помощью eventEmitter, вам необходимосопоставьте его с каким-либо методом родительского компонента.

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

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

Теперь он фактически получает это значение эмиттера, вам необходимо сопоставить его с методом родительского компонента.

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

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

2.Обработка наблюдаемых ошибок.Поскольку вы бросаете Observable, вам нужно будет обработать его в подписке.Подписка на Observable состоит из 3 частей. Ответ , Обработка ошибок , Далее .Теперь вы выдаете ошибку из Observable.throw, ваша часть res не будет запущена.Но вы не обрабатываете ошибки, поэтому ничего не увидите.Вместо этого сделайте это:

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