仅在Google Chrome中的Angular JS中执行代码的周期性奇怪行为

时间:2019-07-01 18:43:27

标签: angularjs google-chrome

我们在其中一个管理页面上遇到了脚本行为不同的问题。仅在Google Chrome浏览器中发现了该问题。

我们在用户界面中输入了日期时间字段:

z(...functions)(x)

enter image description here

以下是脚本正确与错误之间的区别: http://prntscr.com/o96jjb enter image description here http://prntscr.com/o96ju0 enter image description here

我们在Google Chrome 75.0.3770.100上使用Angular JS 1.7.8

这是datetimepicker的剪切代码:

 <datetime-picker ng-model="io.start"
                                          name="start"
                                          min="getMinStartDate()"
                                          max="getMaxStartDate()"
                                          date-title="startDateTitle"
                                          time-title="startTimeTitle"
                                          default-time=""
                                          timezone="timezone"
                                          disabled="startDisabled"
                                          required></datetime-picker>

然后编辑控制器剪切代码:

// DATETIME PICKER
/*
  globals moment
*/
(function(angular) {
  'use strict';

  var app = angular.module('asDMgr');

  app.directive('datetimePicker', function() {

   ...
    return {
      restrict: 'E',
      replace: true,
      templateUrl: '/app/modules/static/tpl/datetime-picker.html',
      scope: {
        ngModel: '=',
        min: '=',
        max: '=',
        timezone: '=',
        disabled: '=',
        dateTitle: '=',
        timeTitle: '=',
        required: '@',
        name: '@',
        infoMsg: '@',
        defaultTime: '@', // leave empty if default time is NOW
      },
      link: function($scope, $element, $attrs) {
        ...     


        /**
         * MIN TIME
         */
        $scope.$watch('min', function(newVal) {
          console.log("DATETIME PICKER MIN");  
          if (newVal) {
            min = newVal;
            var minToPrint = min - $scope.timezoneOffset;
            $scope.minDisplay = printDateTimeFormatted(
              minToPrint,
              dateTimeFormat
            );

            $date
              .data('DateTimePicker')
              .minDate(moment.utc(minToPrint).format(pickerFormat));

            if (
              $scope.minInvalid || // if already invalidated, we still need to update the datetime in error message
              ($scope.ngModel && min > $scope.ngModel)
            ) {
              $scope.ngModel = undefined;
              $scope.displayDate = '';
              $scope.invalid =
                'Min. Date: ' +
                printDateTimeFormatted(minToPrint, dateTimeFormat);
              $scope.minInvalid = true;
            }
          } else {
            min = null;
          }
        });

        /**
         * MAX TIME
         */
        $scope.$watch('max', function(newVal) {
        console.log("DATETIME PICKER MAX");  
          if (newVal) {
            max = newVal;
            var maxToPrint = max - $scope.timezoneOffset;

            if ($scope.min && newVal < $scope.min) {
              // max can not be less than min
              max = null;
              return;
            }

            $scope.maxDisplay = printDateTimeFormatted(
              maxToPrint,
              dateTimeFormat
            );
            $date
              .data('DateTimePicker')
              .maxDate(moment.utc(maxToPrint).format(pickerFormat));

            if ($scope.maxInvalid || ($scope.ngModel && max < $scope.ngModel)) {
              $scope.ngModel = undefined;
              $scope.displayDate = '';
              $scope.maxInvalid = true;
              $scope.invalid =
                'Max. Date: ' +
                printDateTimeFormatted(maxToPrint, dateTimeFormat);
            }
          } else {
            max = null;
          }
        });

        /**
         * Angular init
         */
        $scope.$watch('ngModel', function(newVal) {
          console.log("Datetime picker init");  
          console.log(newVal);
          if (!isValid(newVal) && !$scope.wasInitialised) {
            // first init
            $scope.timeDisplay = defaultTime;
            $scope.wasInitialised = true;

            return;
          } else if (!isValid(newVal) && $scope.wasInitialised) {
            return;
          }

          var datetimeToPrint = newVal - $scope.timezoneOffset;
          $scope.pickerDate = printDateTimeFormatted(
            extractDate(datetimeToPrint),
            pickerFormat
          );
          $scope.displayDate = printDateTimeFormatted(
            extractDate(datetimeToPrint),
            dateFormat
          );
          $scope.timeDisplay = printDateTimeFormatted(
            extractTime(datetimeToPrint),
            timeFormat
          );
        });




        function userActionHandler() {
        console.log("userActionHandler started");  
          var utcMilliseconds = getUserInputInUtcMilliseconds();

          if (validate(utcMilliseconds)) {
            $scope.ngModel = utcMilliseconds;
          } else {
            $scope.ngModel = undefined;
          }

          $scope.$apply();
        }

        $date
          .datetimepicker({
            format: pickerFormat,
            useCurrent: false,
            ignoreReadonly: true,
            debug: false,
          })
          .on('dp.change', function(event) {
            var momentDate = moment.utc($date.val(), pickerFormat).format();

            $scope.displayDate = printDateTimeFormatted(
              extractDate(momentDate.valueOf()),
              dateFormat
            );
            userActionHandler();
          });

        $time.on('change', userActionHandler);
      },
    };
  });
})(window.angular);

InsertionOrderApi.read方法详细信息:

/**
 * Edit Controller
 */
/*
  globals moment
*/
(function(angular) {
  'use strict';

  var app = angular.module('asDMgr');

  app.controller('IOEditController', [
    '$scope',
    '$window',
    '$timeout',
    'IOApi',
    function($scope, $window, $timeout, IOApi) {
      $scope.now = moment
        .utc()
        .seconds(0)
        .milliseconds(0)
        .valueOf();
      $scope.startDateTitle = $scope.endDateTitle = '';
      $scope.startTimeTitle = $scope.endTimeTitle = '';
      $scope.startDisabled = $scope.endDisabled = false;

      // init values
      $scope.io = {
        minEndDate: null,
        minStartDate: null,
      };


      $scope.getMinStartDate = function() {
        console.log("getMinStartDate starts");
        console.log($scope.io);
        if (
          !$scope.io._id || // for new IOs
          !$scope.io.minStartDate || // 
          ($scope.io.minStartDate && $scope.now <= $scope.io.minStartDate) // NOW <= start date
        ) {
          if (
            $scope.io.start &&
            $scope.io.minStartDate &&
            $scope.io.start > $scope.io.minStartDate
          ) {
            $scope.startDisabled = true;
            console.log("getMinStartDate: return null");
            return null;
          } else {
            console.log("getMinStartDate: return now");
            return $scope.now;
          }
        }

        console.log("getMinStartDate: return now");
        return $scope.now;
      };

      $scope.getMaxStartDate = function() {
      console.log("getMaxStartDate starts");
        if (
          $scope.io._id && // for existing IOs
          $scope.io.minStartDate && // if assigned
          !$scope.startDisabled
        ) {
          var max = $scope.io.minStartDate;
          if (max < $scope.getMinStartDate()) {
            console.log("getMaxStartDate: startDisabled = true");
            $scope.startDisabled = true;
          } else {
            console.log("getMaxStartDate: return $scope.io.minStartDate");
            console.log($scope.io.minStartDate);
            return $scope.io.minStartDate;
          }
        }

        console.log("getMaxStartDate: return null");
        return null;
      };


      //$scope.fetch = function() {
            // load io from server
            if (window.ioId) {
                insertionOrderApi.read(window.ioId).then(
                    function (data) {
                        $scope.io = data.io;
                        console.log("IO Received from server!");
                        console.log(data);
                        console.log($scope.io);
                    },
                    function () {
                        console.error('could not load io');
                    }
                );
            } else if (!window.ioId && window.advertiserId) {
                //
            }
      //}





      //$timeout( function(){$scope.fetch();}, 20); // if add this timeout - errors appear very rarely
    },
  ]);
})(window.angular);

我在从服务器接收数据的呼叫中添加了延迟之后,错误几乎消失了(很少出现)


      this.read = function(campaignId) {
        var url = '/campaign/read?id=' + campaignId;

        return $q(function(resolve, reject) {
          $http.get(url).then(
            // success
            function(res) {
              resolve(res.data);
            },
            // error
            function(res) {
              reject();
            }
          );
        });
      };

如何彻底解决此问题?

0 个答案:

没有答案