2016-12-02 61 views
0

我創建了一個節拍器,使用Nativescript Slider(https://docs.nativescript.org/angular/code-samples/ui/slider.html)設置速度(間隔)。Nativescript Slider Value Delayed

此代碼工作就好了(速度變化正確地實時):

app.component.html

<Slider #sl minValue="10" maxValue="350" [(ngModel)]="interval" (valueChange)="setInterval(interval)" row="0" col="1"></Slider> 

app.component.ts

public metronome = sound.create("~/pages/metronome/click.mp3"); 
public interval: number = 120; 
public timer: number; 

start(){ 
    this.stop(); // Stop previous metronome 
    this.tick(); 
} 

stop() { 
    clearTimeout(this.timer); 
} 

setInterval(interval: number) { 
    this.interval = interval; 
} 

public tick() { 
    console.log("Tick"); 
    this.metronome.play(); 
    this.timer = setTimeout(this.tick.bind(this), this.interval); 
} 

但是通過上面的代碼,節拍器使用ms(毫秒)而不是bpm(每分鐘節拍)。音樂家想要在BPM中設置節拍器。

因此:ms = 60'000/BPM(見=> this.plainInterval)

setInterval(){ 
    this.plainInterval = 60000/this.interval; 
} 

public tick() { 
    console.log("Tick"); 
    this.metronome.play(); 
    this.timer = setTimeout(this.tick.bind(this), this.plainInterval); 
} 

現在我的問題: 由於我使用滑塊,該值不正確更新。

i.E .: slider-default是120.好的。然後我滑動到60,數值仍然保持在120 ...然後我滑動到200,現在數值跳到120.我可以繼續滑動到10,現在它是200.

SO:問題是,它檢索舊值。作爲一個新的價值,舊的一個被觸發。

如何同步plainIntervalinterval來解決問題?

+0

'因爲我用的slider' - 你似乎有一個沒有提到這個神話'slider'你實際上是有問題的代碼發佈 - 不能幫你調試代碼你不要發帖 –

+0

對不起,我更新了代碼。這是Nativescript Slider(https://docs.nativescript.org/angular/code-samples/ui/slider.html) – Taremeh

+0

在Angular-2應用程序中,您應該只使用ngModel進行雙向綁定 - 無需在ngModel之後觸發的valueChanged做了同樣的工作(我認爲這會導致你的值比你期望的更「落後」) –

回答

1

我解決了這個問題! this.interval有一個雙向數據綁定,通過[(ngModel)]="interval"。這意味着我不能使用this.plainInterval,因爲它不直接連接到this.interval的雙向數據綁定。 我第一次嘗試使用Pipe,但不允許使用2-Way-Databinding [(ngModel)]。因此,我使用了我的原型(但工作)代碼(我在開頭提供),只調整了this.timer中setTimeout的值。這是工作代碼:

start(){ 
     this.stop(); 
     console.log("START: " + this.interval); 
     this.tick(); 
    } 

stop() { 
    clearTimeout(this.timer); 
} 

setInterval(interval: number) { // This function isn't required 
    this.interval = interval; 
} 

public tick() { 
    console.log("Tick"); 
    this.metronome.play(); 
    this.timer = setTimeout(this.tick.bind(this), 60000/this.interval); // This was the only change needed: 60'000/this.interval 
}