Search code examples
angularjsangularjs-directiveangularjs-scope

AngularJS - directive scope model doesn't update without debugger


For create/edit a website content I have a form with some tabs (buttons making the idea of tabs system because the user may want to add another "tab", etc, etc) and I use a directive to show the selected tab:

<form name="form" novalidate>
    <div class="tabsContainer">
        <!--some button making the idea of tabs system-->
    </div>

    <div class="contentDataContainer">
        <content-form ng-model="VM.CurrentContent" page-features="VM.PageFeatures"></content-form>
    </div>
</form>

When the user want to edit the content I request content data to the web service:

loadData = function () {
    var deferred = $q.defer();

    ContentsService.GetContentToCreateEdit({ id: vm.IdContent })
        .then(function(response)
        {
            try {
                if (vm.IdContent <= 0 || (response.ResultOperation === ResultEnum.Success && exists(response.ResultObject.Contents)))
                {
                    vm.Model = ContentVM.GetModelToShow(response.ResultObject.Contents);
                    vm.CurrentContent = vm.Model[0];
                }
                else 
                {
                    //some like with error messages
                }
            }
            catch (err) { }

        deferred.resolve();              
    }, function () {
        deferred.resolve();
    });

    LoadingService.Load(deferred.promise, 'first');
};

And directive's model must updates.

Directive controller:

vm.Model = { Id: 0 };

function init()
{            
    vm.Model = exists($scope.model) ? $scope.model : getDefaultContentInfo(); 

    if(isStringEmpty(vm.Model.Price)) vm.Model.Price = "";
    vm.Model.PriceText = vm.Model.Price;
    vm.Model.IsIntervalDate = !isStringEmpty(vm.Model.EndDate) && vm.Model.EndDate != vm.Model.StartDate;
};

init();

$scope.$watch($scope.model, function () {
    init();
}, true);

If I put a debugger inside the init() function the directive updates perfectly with the $scope.model but if I haven't it doesn't...

Someone can explain what is happenning here and how can I solve this?

I already tried to use $scope.$apply() but I got a digest error and I already tried to use a $timeout() but directive's model doesn't updates nither.

$timeout(function () {
    init();

    $scope.$watch($scope.model, function () {
        init();
    }, true);
},500);

Solution

  • After implementing a form validation I needed to show model errors and the problem appears again. And finaly after many headaches and found the problem.

    In my $scope.$watch

    $scope.$watch($scope.model, function () {
        init();
    }, true);
    

    The watchExpression must be idempotence and so I change the code to this

    $scope.$watch('model', function () {
        init();
    }, true);
    

    And now works!!!

    For more documentation click here