How can I overcome race conditions in directives without a timeout function?

I am trying to create a directive. Things just didn’t work, so I simplified the situation until I found this basic problem with the conditions of the race, causing problems for me. In my control controller, I need to do some checks, for example ...

if ($scope.test.someValue === true) { $scope.test.anotherValue += 1; }

Here is my main directive with some magazines to illustrate how this problem manifests itself.

app.directive('myDirective', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            test: '='
        },
        template: '<div><pre>{{ test | json }}</pre></div>',
        controller: function ($scope, $timeout) {

        // this logs undefined
        console.log($scope.test);

        // this logs the scope bound 'test' object
        $timeout(function() {
            console.log($scope.test);
        }, 300);

        }
    };
});

What is the correct way to deal with this race condition? I am worried that in the real world this timeout function will work or not work depending on how long the api call will take.

+4
source share
3 answers

, "link" ( ) $scope.test - , undefined

$timeout(fn, timeout) - -, - $. $timeout() 0, . , $timeout (...) $digest().

: $timeout() $digest()

, , :

$scope.$watch("test.somevalue", function(new_val, old_val) {
    console.log("somevalue changed!! - increment othervalue");
    $scope.othervalue += 1;
});
+4

( - ).

- , - .

( , ) (.. link ).

app.directive('myDirective', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            test: '='
        },
        template: '<div><pre ng-click="someFunc()">{{ test | json }}</pre></div>',
        controller: function ($scope) {
            /* No two-way bindings yet: test -> undefined */

            /* Business logic can go here */
            $scope.someFunc = function () {
                alert('I implement the business logic !');
            };
        },
        link: function postLink(scope, elem, attrs) {
            /* Bindings are in place. Safe to check up on test. */
            console.log($scope.test);
        }
    };
});
+1

$watch , , (!= undefined ) . , , $digest. :

$scope.$watch('test', function(val){
    if(val != undefined) {
        if ($scope.test.someValue === true) { $scope.test.anotherValue += 1; }
    }
})
0

Source: https://habr.com/ru/post/1541900/


All Articles