为什么当监视表达式中的滑块选项更新时,AngularJS 滑块 (rzslider) 无法正确更新?



我有一个设置为默认值的rzslider。

.HTML:

<div id="slider">
<rzslider class="with-legend"
rz-slider-model="slider.value"
rz-slider-options="slider.options"> 
</rzslider>
</div>

Javascript:

$scope.slider = {
this.value = 0;
this.options = {
floor: 0,
ceil: 0
}

在监视表达式中,有更新滑块选项的代码:

$scope.$watch('foo', function () {
$scope.slider.value = 0;
$scope.slider.options.floor = 0;
$scope.slider.options.ceil = foo.length;
}

运行监视表达式中的代码后,我希望滑块的上限选项会更改。但是,即使$scope.slider的值已正确更新,更改也不会显示在滑块本身上。

我尝试按照 AngularJS 滑块 Github 页面上的文档重新渲染滑块,但它不能解决问题。

$scope.refreshSlider = function() {
$timeout(function() {
$scope.$broadcast('rzSliderForceRender')
})
}

经过一番挖掘,我们发现这是一个时间问题。请注意,这只是第一个角度摘要周期中的问题,当 rzslider 设置为默认值并由同一摘要周期中的监视表达式更新时。

rzslider 更新选项代码和角度监视表达式代码的组合会导致 rzslider 在第一个摘要周期中错过更新。

这是 rzslider 更新选项代码:

this.scope.$watch('rzSliderOptions()', function(newValue, oldValue) {
if (newValue === oldValue)
return;
self.applyOptions(); // need to be called before synchronizing the values
self.syncLowValue();
if (self.range)
self.syncHighValue();
self.resetSlider();
}, true);

这是调用 rzslider 更新选项代码的角度监视表达式代码:

watch.fn(value, ((last === initWatchVal) ? value : last), current);

在第一个摘要循环中,last等于initWatchVal,因为(根据角度)没有变化。 确定旧值

这意味着 rzslider 代码中的newValueoldValue都包含滑块选项的更新版本。比较这些值时,函数会在调用self.applyOptions();之前返回,这将更新滑块。

有两种可能的解决方案:

  1. 在第一个摘要循环完成运行后更新滑块选项。这可以使用超时或将更新代码添加到按钮单击事件来完成。

  2. 在滑块
  3. 选项更新后渲染滑块。我们通过 将 rzslider 放入ng-if.当我们显示元素时,从一开始就使用更新的值创建 rzslider。

下面更新范围内数据的解决方案。 当你创建一个onclick函数(onclick)时,你应该放到这个范围内。

let commissionsValue=0;
let interestRate=0;  
let benefits=0;
let result=0;
$scope.onclick= function () {   
$scope.verticalSlider1.value = commissionsValue;
$scope.verticalSlider2.value = interestRate;
$scope.verticalSlider3.value = benefits;
$scope.$broadcast('rzSliderForceRender');
}

完整代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Index</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
<link rel="stylesheet" href="https://rawgit.com/rzajac/angularjs-slider/master/dist/rzslider.css" />
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://rawgit.com/rzajac/angularjs-slider/master/dist/rzslider.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<script type="text/javascript">

let commissionsValue=0;
let interestRate=0;  
let benefits=0;
let result=0;
var app = angular.module('MyApp', ['rzSlider']);
app.controller('MyController', function ($scope, $window) {
$scope.verticalSlider1 = {
value: commissionsValue,
options: {
floor: 0,
ceil: 100,
vertical: true,
showSelectionBar: true
}
};
$scope.verticalSlider2 = {
value: interestRate,
options: {
floor: 0,
ceil: 100,
vertical: true,
showSelectionBar: true
}
};
$scope.verticalSlider3 = {
value: benefits,
options: {
floor: 0,
ceil: 100,
vertical: true,
showSelectionBar: true
}
};
$scope.progress = {
value: result,
options: {
floor: 0,
ceil: 300,
vertical: false,
showSelectionBar: true,
readOnly: true,
}
};
$scope.upload = function () {   
var files = document.getElementById('file_upload').files;
if(files.length==0){
alert("Please choose any file...");
return;
}
var filename = files[0].name;
var extension = filename.substring(filename.lastIndexOf(".")).toUpperCase();
if (extension == '.XLS' || extension == '.XLSX') {
var reader = new FileReader();
reader.readAsBinaryString(files[0]);
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type : 'binary'
});
var result = {};
var firstSheetName = workbook.SheetNames[0];
var jsonData = XLSX.utils.sheet_to_json(workbook.Sheets[firstSheetName]);
commissionsValue = parseInt(jsonData[0].commissions);
interestRate = parseInt(jsonData[0].interestRate);
benefits = parseInt(jsonData[0].benefits);
result= commissionsValue+interestRate+benefits;
$scope.verticalSlider1.value = commissionsValue;
$scope.verticalSlider2.value = interestRate;
$scope.verticalSlider3.value = benefits;
$scope.$broadcast('rzSliderForceRender');
}
}else{
alert("Please select a valid excel file.");
}
}
}); 
</script>
</head>
<body ng-app="MyApp" ng-controller="MyController">
<div class="container">
<input type="file" id="file_upload" />
<button type="button" ng-click="upload()">Try it</button>
<div class="card border-secondary mb-3" style="max-width: 40rem;">
<div class="card-header">
<div class="row">
<div class="col-8"><rzslider rz-slider-model="verticalSlider1.value + verticalSlider2.value + verticalSlider3.value" rz-slider-options="progress.options"></rzslider></div>
<div class="col-4" style="
margin: auto;
padding: 10px;
text-align: center;
"> <strong>Total: </strong> {{ verticalSlider1.value + verticalSlider2.value + verticalSlider3.value }} <i class='fa fa-euro' style='font-size:15px'></i> </div>
</div>
</div>
<div class="card-body text-secondary">
<rzslider id="Text1" rz-slider-model="verticalSlider1.value" rz-slider-options="verticalSlider1.options" style="height: 200px; width: 220px;"></rzslider>
<rzslider rz-slider-model="verticalSlider2.value" rz-slider-options="verticalSlider2.options" style="height: 200px; width: 220px"></rzslider>
<rzslider rz-slider-model="verticalSlider3.value" rz-slider-options="verticalSlider3.options" style="height: 200px;"></rzslider>
</div>
</div>

</div>
</body>
</html>

Excel文件:

Excel文件

最新更新