2017-05-29 16 views
6

Tôi đang làm việc trên bộ chọn ngày để triển khai bộ chọn phạm vi trên AngularUI.Cách sử dụng ng-thay đổi và ng-mô hình trong chỉ thị tùy chỉnh - vòng lặp tiêu hóa

Một mã html để gọi thời gian chọn tùy chỉnh:

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

Dưới đây là chỉ thị của tôi:

mô-đun 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); 
     } 
    } 
} 

Đây là cách nó đang làm việc:

Date Picker with sliders

Nhưng tôi recived một lỗi của: 10 $ digest()

> 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 

Trả lời

2

tôi đã thay đổi ngChange vào onUpdate.

Trong html:

on-update="updateHours()" 

tôi thêm vào trong thay đổi từ ngCgange; trong chỉ thị để

onUpdate:() => any; 

Bind phạm vi:

onUpdate: "&",

aldo gọi là phương pháp thêm

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

Tìm kiếm câu trả lời trong ngoại lệ của bạn:

Trình xem được kích hoạt trong 5 lần lặp gần nhất: [[{ "msg": "fn: ngModelWatch", "newVal": "2017-05-28T22: 00: 00.000Z", "oldVal": "2017-05-28T22: 00: 00.000Z"} ...]]

Hình như bạn có vấn đề trong:

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

bạn nghe trên this.$scope.ngModel và đối với một số phương pháp lý this.showPercentage() hoặc this.drawRangeTrace() thay đổi ngModel bạn mà bắn thêm người quan sát.

Để tránh rò rỉ bộ nhớ Góc di chuyển ngoại lệ này để thoát khỏi vòng lặp chu trình tiêu hóa vô hạn.


Cố gắng đơn giản hóa mã của bạn để tìm đoạn mã có vấn đề bằng sự khởi đầu dòng chú thích bởi nội dung dòng phương pháp this.showPercentage()this.drawRangeTrace()

+1

Bây giờ tôi lấy ng thay đổi từ chỉ còn từ mẫu trong chỉ thị và Tôi đã thêm "hardcode" này vào trình xem ngModel này. $ Scope. $ Parent.updateMinutes(); này. $ Scope. $ Parent.updateHours(); – Andrej

Các vấn đề liên quan