Using ng-change and ng-model in user directive - digest loop

I am working on a date installer to implement a range selector on AngularUI.

Html code to call custom timer:

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

Here is my directive:

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

Here's how it works:

Select date with sliders

But I got an error: 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
+6
source share
2 answers

I changed ngCange to onUpdate.

In html:

on-update="updateHours()"

I added to ngCgange; in the directive

onUpdate: () => any;

Bind scope:

onUpdate: "&",

aldo called the add method

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);
        }
    }
+2
source

Find the answer in your exception:

Observers fired in the last 5 iterations: [[{"" 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, digest.


, , this.showPercentage() this.drawRangeTrace()

+1

All Articles