Skip to content

Commit 484684d

Browse files
author
Valentin Hervieu
committed
fix(): Change the watchers order to prevent unwanted model modifications
The order of watchers definition set the order in which their callback will be called when 2 watched values are modified simultaneously. If the slider value is changed along with the precision options, we want the value to be parsed with the new precision. Closes #207
1 parent e9c097e commit 484684d

File tree

3 files changed

+65
-25
lines changed

3 files changed

+65
-25
lines changed

dist/rzslider.js

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@
243243
*/
244244
this.initHasRun = false;
245245

246+
/**
247+
* Internal flag to prevent watchers to be called when the sliders value are modified internally.
248+
* @type {boolean}
249+
*/
250+
this.internalChange = false;
251+
246252
// Slider DOM elements wrapped in jqLite
247253
this.fullBar = null; // The whole slider bar
248254
this.selBar = null; // Highlight between two handles
@@ -328,14 +334,26 @@
328334
self.resetSlider();
329335
});
330336

331-
// Watchers
337+
// Watchers (order is important because in case of simultaneous change,
338+
// watchers will be called in the same order)
339+
this.scope.$watch('rzSliderOptions', function(newValue, oldValue) {
340+
if (newValue === oldValue)
341+
return;
342+
self.applyOptions();
343+
self.resetSlider();
344+
}, true);
345+
332346
this.scope.$watch('rzSliderModel', function(newValue, oldValue) {
347+
if(self.internalChange)
348+
return;
333349
if (newValue === oldValue)
334350
return;
335351
thrLow();
336352
});
337353

338354
this.scope.$watch('rzSliderHigh', function(newValue, oldValue) {
355+
if(self.internalChange)
356+
return;
339357
if (newValue === oldValue)
340358
return;
341359
if (newValue != null)
@@ -346,13 +364,6 @@
346364
}
347365
});
348366

349-
this.scope.$watch('rzSliderOptions', function(newValue, oldValue) {
350-
if (newValue === oldValue)
351-
return;
352-
self.applyOptions();
353-
self.resetSlider();
354-
}, true);
355-
356367
this.scope.$on('$destroy', function() {
357368
self.unbindEvents();
358369
angular.element($window).off('resize', calcDimFn);
@@ -1442,8 +1453,7 @@
14421453
this.scope.rzSliderHigh = newMaxValue;
14431454
this.updateHandles('rzSliderModel', newMinOffset);
14441455
this.updateHandles('rzSliderHigh', newMaxOffset);
1445-
this.scope.$apply();
1446-
this.callOnChange();
1456+
this.applyModel();
14471457
},
14481458

14491459
/**
@@ -1491,8 +1501,7 @@
14911501
}
14921502

14931503
if (valueChanged) {
1494-
this.scope.$apply();
1495-
this.callOnChange();
1504+
this.applyModel();
14961505
}
14971506
return switched;
14981507
},
@@ -1519,6 +1528,17 @@
15191528
}
15201529

15211530
return eventNames;
1531+
},
1532+
1533+
/**
1534+
* Apply the model values using scope.$apply.
1535+
* We wrap it with the internalChange flag to avoid the watchers to be called
1536+
*/
1537+
applyModel: function() {
1538+
this.internalChange = true;
1539+
this.scope.$apply();
1540+
this.callOnChange();
1541+
this.internalChange = false;
15221542
}
15231543
};
15241544

0 commit comments

Comments
 (0)