Angular Directive attrs.$observe

ttmt picture ttmt · Feb 21, 2014 · Viewed 39.5k times · Source

I found this Angular Directive online to add a twitter share button. It all seems staright forward but I can't work out what the attrs.$observe is actually doing.

I have looked in the docs but can't see $observe referenced anywhere.

The directive just seems to add the href which would come from the controller so can anyone explain what the rest of the code is doing?

module.directive('shareTwitter', ['$window', function($window) {

    return {
        restrict: 'A',
        link: function($scope, element, attrs) {

            $scope.share = function() {

                var href = 'https://twitter.com/share';

                $scope.url = attrs.shareUrl || $window.location.href;
                $scope.text = attrs.shareText || false;

                href += '?url=' + encodeURIComponent($scope.url);
                if($scope.text) {
                    href += '&text=' + encodeURIComponent($scope.text);
                }

                element.attr('href', href);
            }

            $scope.share();

            attrs.$observe('shareUrl', function() {
                $scope.share();
            });

            attrs.$observe('shareText', function() {
                $scope.share();
            });
        }
    }
}]);


<a href="" target="_blank" share-twitter share-url="[[shareTwitterUrl]]" share-text="[[shareTwitterText]]">Twitter</a>

Answer

Erex picture Erex · Feb 21, 2014

In short:

Everytime 'shareTwitterUrl' or 'shareTwitterText' changes, it will call the share function.

From another stackoverflow answer: (https://stackoverflow.com/a/14907826/2874153)

$observe() is a method on the Attributes object, and as such, it can only be used to observe/watch the value change of a DOM attribute. It is only used/called inside directives. Use $observe when you need to observe/watch a DOM attribute that contains interpolation (i.e., {{}}'s). E.g., attr1="Name: {{name}}", then in a directive: attrs.$observe('attr1', ...). (If you try scope.$watch(attrs.attr1, ...) it won't work because of the {{}}s -- you'll get undefined.) Use $watch for everything else.

From Angular docs: (http://docs.angularjs.org/api/ng/type/$compile.directive.Attributes)

$compile.directive.Attributes#$observe(key, fn);

Observes an interpolated attribute.

The observer function will be invoked once during the next $digest fol lowing compilation. The observer is then invoked whenever the interpolated value changes.