2017-05-29 58 views
6

我正在使用日期选择器在AngularUI上实现范围选择器。在自定义指令中使用ng-change和ng-model - 摘要循环

的HTML代码来调用自定义的时间选择:

<time-range 
     name-time="Hours" 
     max-length="2" min="00" max="23" step="01" 
     ng-model="hours" 
     ng-change="updateHours()"> 
    </time-range> 
<time-range 
     name-time="Minutes" 
     max-length="2" min="00" max="59" step="01" 
     ng-model="minutes" 
     ng-change="updateMinutes()"> 
    </time-range> 

这里是我的指令:

模块app.common.directives {

export interface ITimeRangeScope extends ng.IScope { 
     ngModel: string; 
     ngChange; 
     nameTime: string; 
     maxLength: number; 
     min: number; 
     max: number; 
     step: number; 
     vm: TimeRangeController; 
    } 

    export class TimeRange implements ng.IDirective { 
     scope: any = { 
      ngModel: "=", 
      ngChange: "=", 
      nameTime: "@", 
      maxLength: "@", 
      min: "@", 
      max: "@", 
      step: "@" 
     }; 
     controller = TimeRangeController; 

     template = ` 
      <div class="custom-range-slider"> 
       <span> {{nameTime}}: </span> 
       <div style="padding-bottom: 5px;"></div> 
       <input type="range" max-length="{{maxLength}}" min="{{min}}" max="{{max}}" step="{{step}}" ng-model="ngModel"ng-change="ngChange"> 
      </div> 
     `; 

     restrict: string = "E"; 

     //Use this to register this directive 
     static factory(): ng.IDirectiveFactory { 
      var directive: ng.IDirectiveFactory =() => new TimeRange(); 
      return directive; 
     } 
    } 

    class TimeRangeController { 
     init; 
     val; 

     // @ngInject 
     constructor(
      private $scope: ITimeRangeScope, 
      private $element: ng.IAugmentedJQuery, 
      private $attrs, 
      private $transclude 
     ) { 
      $scope.vm = this; 

      this.$scope.$watch("ngModel",() => { 
       this.showPercentage(); 
       this.drawRangeTrace(); 
      }); 
     } 

     showPercentage() { 
      this.init = parseInt(this.$scope.ngModel); 
      var min = parseInt(this.$element.attr('min')); 
      var max = parseInt(this.$element.attr('max')); 
      this.val = (this.init - min)/max - min; 
     } 

     drawRangeTrace() { 
      this.$element.children().find('input').css('background-image', 
       '-webkit-gradient(linear, left top, right top, ' 
       + 'color-stop(' + this.val + ', #2196F3), ' 
       + 'color-stop(' + this.val + ', #C5C5C5)' 
       + ')' 
      ); 
      this.$element.children().find('input').val(this.init); 
     } 
    } 
} 

这是它是如何工作的:

Date Picker with sliders

但我recived的一个错误:在您的异常10 $摘要()

> vendor.min.js:84275 Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [[{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"}],[{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"}],[{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"}],[{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"}],[{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"},{"msg":"fn: ngModelWatch","newVal":"2017-05-28T22:00:00.000Z","oldVal":"2017-05-28T22:00:00.000Z"}]] 
http://errors.angularjs.org/1.6.1/$rootScope/infdig?p0=10&p1=%5B%5B%7B%22ms…%3A00.000Z%22%2C%22oldVal%22%3A%222017-05-28T22%3A00%3A00.000Z%22%7D%5D%5D 
    at vendor.min.js:84275 
    at Scope.$digest (vendor.min.js:102059) 
    at Scope.$apply (vendor.min.js:102287) 
    at vendor.min.js:104131 
    at completeOutstandingRequest (vendor.min.js:90318) 
    at vendor.min.js:90597 

回答

2

我改变ngChange到的onUpdate。

在HTML:

on-update="updateHours()" 

我在从ngCgange改变加入;在指令

onUpdate:() => any; 

绑定范围:

onUpdate: "&",

阿尔称为方法添加

class TimeRangeController { 
     init; 
     val; 
     onUpdate; // Override callback for adding an entity to the list 

     // @ngInject 
     constructor(
      private $scope: ITimeRangeScope, 
      private $element: ng.IAugmentedJQuery, 
      private $attrs, 
      private $transclude 
     ) { 
      $scope.vm = this; 

      this.$scope.$watch("ngModel",() => { 
       this.showPercentage(); 
       this.drawRangeTrace(); 
       this.add(); 
      }); 
     } 

     add() { 
      if (this.$attrs.onUpdate != undefined) { 
        this.$scope.onUpdate(); 
       } 
     } 

     showPercentage() { 
      this.init = parseInt(this.$scope.ngModel); 
      var min = parseInt(this.$element.attr('min')); 
      var max = parseInt(this.$element.attr('max')); 
      this.val = (this.init - min)/max - min; 
     } 

     drawRangeTrace() { 
      this.$element.children().find('input').css('background-image', 
       '-webkit-gradient(linear, left top, right top, ' 
       + 'color-stop(' + this.val + ', #2196F3), ' 
       + 'color-stop(' + this.val + ', #C5C5C5)' 
       + ')' 
      ); 
      this.$element.children().find('input').val(this.init); 
     } 
    } 
1

搜索答案:

观察者在最近的5次迭代中解雇了[[{ “msg”:“fn: ngModelWatch”,“newVal”:“2017-05-28T22:00:00.000Z”,“oldVal”:“2017-05-28T22:00:00.000Z”} ...]]]

看起来像你这样的问题:

this.$scope.$watch("ngModel",() => { 
      this.showPercentage(); 
      this.drawRangeTrace(); 
     }); 

你听上this.$scope.ngModel出于某种原因,方法this.showPercentage()this.drawRangeTrace()更改ngModel将触发额外的守望者。

为避免内存泄漏,Angular会抛出此异常以摆脱无限摘要循环循环。


尽量简化你的代码,发现有问题的代码片段由开始注释行的方法this.showPercentage()线内容和this.drawRangeTrace()

+1

现在我删除从指令还指令NG-变化的模板,我在ngModel watcher上添加了这个“hardcode”。$ scope。$ parent.updateMinutes(); this。$ scope。$ parent.updateHours(); – Andrej