Search code examples
angularjsangularjs-directiveangularjs-scopenvd3.jsangular-nvd3

Inheritance in AngularJs Directives link function


I'm currently using a custom directive in Angular to resize my angular-nvd3 charts by watching for a resize on the parent div. This works but I have to redraw every chart on even a single chart being resized.

Is it possible to override the updateHeight and updateWidth function in derived custom directive to refresh each individual chart so I don't have to duplicate code by creating separate directives.

angular.module('app.graphs').directive('flexibleDiv', function () {
    return {
        scope: {
            opts: '=' 
        },
        link: function (scope, element, attr) {

            // Watching height of parent div
            scope.$watch(function () {
                return element.parent(0).height();
            }, updateHeight);

            // Watching width of parent div
            scope.$watch(function () {
                return element.parent(0).width();
            }, updateWidth);

            function updateHeight() {
                scope.$parent.scatter_api.refresh();
                scope.$parent.focus_api.refresh();
                scope.$parent.scatter_twoaxis_api.refresh();
            }

            function updateWidth() {
                scope.$parent.scatter_api.refresh();
                scope.$parent.focus_api.refresh();
                scope.$parent.scatter_twoaxis_api.refresh();
            }
        }
    }

 <div class="widget-body no-padding" flexible-div>
        <nvd3-scatter-chart data="scatter_data" api="scatter_api"></nvd3-scatter-chart>
         </div>
  </div>

Solution

  • The directive can use an expression binding to define the parent expression to invoke on an event:

    angular.module('app.graphs').directive('flexibleDiv', function () {
        return {
            scope: {
                opts: '=',
                onUpdateSize: '&' 
            },
            link: function (scope, element, attr) {
    
                // Watching height of parent div
                scope.$watch(function () {
                    return element.parent(0).height();
                }, updateSize);
    
                // Watching width of parent div
                scope.$watch(function () {
                    return element.parent(0).width();
                }, updateSize);
    
                function updateSize() {
                    scope.onUpdateSize();
                }
    
            }
        }
    

    HTML

    <div flexible-div on-update-size="scatter_api.refresh()">
        <nvd3-scatter-chart data="scatter_data" api="scatter_api">
        </nvd3-scatter-chart>
    </div>
    

    From the Docs:

    The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the directive's element. These local properties are useful for aliasing values for templates. The keys in the object hash map to the name of the property on the isolate scope; the values define how the property is bound to the parent scope, via matching attributes on the directive's element:

    • & or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name.

    --AngularJS Comprehensive Directive API Reference -- Scope