简体   繁体   English

角度4:组件和服务之间的更改检测

[英]Angular 4: Change Detection between component and service

I am currently working on a small test project with Ionic/Angular , Before I post the snippets: the problem I have is that I want to send value changes from inside a service (@Injectable) to a component to track it's changes. 我目前正在使用Ionic/Angular进行小型测试项目,然后发布代码片段:我(@Injectable)的问题是我想将值更改从服务内部(@Injectable)发送到component以跟踪其更改。 I have tried EventEmitter and OnChanges, but to no avail.. 我已经尝试过EventEmitter和OnChanges,但无济于事。

I have a progressbar that needs a certain value to advance in progress. 我的进度栏需要一定的值才能进行。 This is the progressbar: TS: 这是进度条: TS:

import {Component, Input} from '@angular/core';


@Component({
  selector: 'progressbar',
  templateUrl: 'progressbar.html'
})
export class ProgressBarComponent {

  @Input('progress') progress;

  constructor() {}
}

html HTML

<div class="progress-outer">
    <div class="progress-inner" [style.width]="progress + '%'">
        {‌{progress}}%
    </div>
</div>

(credit to JoshMorony) The bar's width attribute is connected to the progress, thus enabling it to advance eg by percentage. (贷记为JoshMorony)条的width属性与进度相关,因此使进度可以按百分比进行。

Now comes the problem: 现在出现了问题:

I injected the progressbar into a normal component, but the calculation for the advancement happens in a different service, an Injectable. 我将进度条注入了正常组件,但是进度的计算发生在另一项服务中,即Injectable。 I am only able to send a single value, but not the advancement of the calculation and as such the bar itself: 我只能发送一个值,但不能发送计算的进度,因此不能发送小节本身:

home.ts home.ts

showProgressBar: boolean;
// this variable must always have a value between 0 - 100
loadProgress;

triggerEvent(){
this.service.showProgressbar = true;
}

home.html home.html的

<progressbar [progress]="loadProgress"></progressbar>

What is done here is simply a call to trigger an event, that includes the logic for that progressBar. 此处完成的只是触发事件的调用,其中包括该progressBar的逻辑。 By setting service'sshowProgressbar to true, I am indirectly setting the pages showprogressbar to true as well. 通过将service'sshowProgressbar设置为true,我也间接将页面showprogressbar设置为true。

Note: the boolean is not used yet 注意:布尔值尚未使用

Service looks like this: 服务看起来像这样:

denominator: number = 0;
counter: number = 0;
showProgressbar = false;

result: number = 0;
calculateProgress() {
  if (this.showProgressbar = true) {
    let percentage = Math.round((this.counter / this.denominator) * 100);
    this.result = percentage;
    if (this.result == 100) {
      setTimeout(this.showProgressbar = false, 500);
    }
  } else {
    this.counter = 0;
    this.denominator = 0;
    this.result = 0;
  }
}

I checked the calls, result here DOES calculate correctly, but it does not transfer to home.ts unfortunately. 我检查了呼叫,这里的结果可以正确计算,但是很遗憾,它不会转移到home.ts。 If I statically change result to a random number like 50 or so, it will indeed change the bar. 如果我将结果静态更改为50左右的随机数,则确实会改变标准。

How can I make home.ts "watch" the value of result constantly or in another way how do I implement the change detection for that result value here? 如何使home.ts “观察”结果的值,或者如何在此处实现对该结果值的更改检测?

THANKS! 谢谢!

You can create an Observable of the service and subscribe in home.ts 您可以创建服务的Observable并在home.ts中进行订阅

Your service 您的服务

//create a Subject
private percentSource:Subject<any>=new Subject<any>();
//create a Observable
percentEvent:Observable<any>=this.percentSource.asObservable();
...
calculateProgress() {
  if (this.showProgressbar = true) {
    ...
    //send a change of observable with next
    this.percentSource.next(percentage);  //return as result the percent
    ...
  } else {
     ...
  }
}

then, in your home you can subscribe to the observable in the function tiggerEven or in progressBar.component in the ngOnInit function 然后,您可以在家中的tiggerEven函数中或ngOnInit函数的progressBar.component中订阅可观察的内容

triggerEvent(){
    this.service.showProgressbar = true;
    //takeWhile make you unsubscribe if condition is not successfully
    //NOT put if you subscribe in your progressBar.component
    this.service.percentEvent
    .takeWhile(() =>this.progress!=100)
    .subscribe(result=>  
    {
         this.progress=result;
    } 
}

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

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