简体   繁体   中英

Angular watch cycle

I'd like to create a color picker based on farbtastic color picker . What I'm trying to achieve is adding RGB sliders that I want to link to the color wheel. Here's what I have so far.

app.controller('PickAColorController', function ($scope) {
$('#colorpicker').farbtastic(function (col) {
    $scope.$apply(function () {
        $scope.color.setColor(col);
    });
});

$scope.$watch('color.r', function () {
    var color = chroma($scope.color.r, $scope.color.g, $scope.color.b);
    var cp = $.farbtastic('#colorpicker');
    cp.setColor(color.hex());
})

$scope.color = {
    hex:'',
    r: 0,
    g: 0,
    b: 0,

    setColor: function (hexCode) {
        this.hex = hexCode;
        var rgb = chroma(hexCode).rgb(); 
        this.r = rgb[0];
        this.g = rgb[1];
        this.b = rgb[2];
    }
};
});

It works fine without the watch but with it I get

 Error: [$rootScope:inprog] http://errors.angularjs.org/1.3.14/$rootScope/inprog?p0=%24digest
 at Error (native)
 ...

which, I suspect, is due to my modification to the color that triggers another change to my watched variable and so on... leading to a cycle and if I'm not mistaken after a couple of runs angular terminates this and throws an error. So can you suggest a clean way to overcome this issue?

You can probably use $timeout which will call $apply internally but will be pushed to end of digest queue and thus avoid the in progress error.

$('#colorpicker').farbtastic(function (col) {
    $timeout(function () {
        $scope.color.setColor(col);
    });
});

Don't forget to inject $timeout in controller.

Note- DOM manipulation code like this doesn't belong in controller and should always be placed in directives

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM