Search code examples
angularjsangularjs-scopeangularjs-watch

AngularJS custom error directive not detecting data changes


I am writing a custom angular directive so that I can use it across many pages on a site to give a similar feel of errors to users. To do this, I have created the directive shown below.

angular.module('ErrorMessages', []);

angular.module('ErrorMessages').directive('errorMessage', function () {
    return {
        templateUrl: '/Scripts/Directives/ErrorDirective/Error.html',
        restrict: 'AE',
        multiElement: true,
        scope: {
            resultData: '@'
        },
        link: function (scope, elem, attrs) {
            alert('result data is: ' + attrs.resultData);
            scope.$watch(attrs.resultData, function (value) {
                alert(value);
                if (value == undefined || value.length == 0) {
                    alert('Dont show error');
                        scope.ShowError = false;
                } else {
                    alert('show error');
                        scope.ShowError = true;
                        scope.Messages = value;
                    }
                });
            }
    }
});

Current Template is here.

<div style="color: red;" ng-show="ShowError">
    <div class="row">
        <div class="col-md-12">
            <h1>Error</h1>
        </div>
    </div>
    <div class="row ">
        <div class="col-md-12 error">
            <ul>
                <li ng-repeat="message in Messages">{{message}}</li>
            </ul>
        </div>
    </div>
</div>

I then mark it up on the html page as such.

<error-Message result-data="Errors"></error-Message>

What I want to be able to do is set the Errors variable on the controller and have the error show or hide.

$scope.Errors = [];
$scope.Errors.push('error text');

But when I do this, it doesn't appear that the watch is being triggered. Thanks for any help.


Solution

  • USE $watchCollection:

         ̶s̶c̶o̶p̶e̶.̶$̶w̶a̶t̶c̶h̶(̶a̶t̶t̶r̶s̶.̶r̶e̶s̶u̶l̶t̶D̶a̶t̶a̶,̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶v̶a̶l̶u̶e̶)̶ ̶{̶ 
         scope.$watchCollection(attrs.resultData, function (value) {
    

    or USE deep $watch:

        scope.$watch(attrs.resultData, function (value) {
            alert(value);
            if (value == undefined || value.length == 0) {
                alert('Dont show error');
                    scope.ShowError = false;
            } else {
                alert('show error');
                    scope.ShowError = true;
                    scope.Messages = value;
                }
            ̶}̶)̶;̶
            //USE DEEP WATCH
            }, true);
    

    Dirty checking can be done with three strategies: By reference, by collection contents, and by value. The strategies differ in the kinds of changes they detect, and in their performance characteristics.

    For more information, see