javascript 为什么在监视表达式中更新滑块选项时,AngularJS Slider(rzslider)不能正确更新?

q9yhzks0  于 2023-03-06  发布在  Java
关注(0)|答案(2)|浏览(128)

我有一个设置为默认值的rzslider。
超文本:

<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;
}

运行watch表达式中的代码后,我希望滑块的ceiling选项发生变化,但是,即使$scope.slider的值已经正确更新,滑块本身也不会发生变化。
我已经尝试重新呈现AngularJS Slider Github页面上记录的滑块,但它没有解决这个问题。

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

bbmckpt71#

经过深入研究,我们发现这是一个时间问题,注意,这只是在第一个角摘要周期中的问题,当rzslider被设置为默认值***并且***在同一个摘要周期中被监视表达式更新时。
rzslider更新选项代码和Angular 监视表达式代码的组合导致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更新选项代码的Angular 监视表达式代码:

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

在第一个摘要循环中,last等于initWatchVal,因为(根据Angular )没有变化。Determining oldValue
这意味着rzslider代码中的newValueoldValue都包含更新版本的滑块选项,当比较这些值时,函数在调用self.applyOptions();之前返回,self.applyOptions();将更新滑块。
有两种可能的解决方案:
1.* 在第一个摘要循环完成运行后更新滑块选项。* 这可以通过使用超时或向按钮单击事件添加更新代码来完成。
1.* 在滑块选项已经更新后渲染滑块。* 我们通过将rzslider放入ng-if中来实现这一点。当我们显示元素时,rzslider从一开始就使用更新后的值创建。

lmvvr0a8

lmvvr0a82#

下面是更新作用域中数据的解决方案。当你创建一个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 File

相关问题