Rectangle 27 0

javascript How to make directives look for two parameters?


.directive('chart', function() {
           return {
             templateUrl:'chart.html',
             replace:true,
             restrict: 'E',
             scope: {
                type:'@', 
                legend:'@'
             }                  
           }
        })
<chart details='showDetails(legend)'></chart>
<div> {{type}} {{legend}} </div>
app.directive("chart", function() {
    return {
      scope: {
        details: "&"
      },
      template: '<input type="text" ng-model="value">' +
        '<div class="button" ng-click="details({legend:value})">Show Details</div>'
    }
  })
scope.type = $parent.myModel.type
  scope.legend = $parent.myModel.legend
.directive('chart', function() {
           return {
             templateUrl:'chart.html',
             replace:true,
             restrict: 'E',
             scope: {
                type:'=', 
                legend:'='
             }                  
           }
        })
<chart type="myModel.type" legend="myModel.legend" />
angular.module('myModule',[])
        .directive('chart', function() {
           return {
             templateUrl:'chart.html',
             replace:true,
             restrict: 'E',
             scope: {
                type:'=', 
                legend:'='
             }                  
           }
        })
scope.type='true'
 scope.legend='type-one'

After that you can change both properties in the parent scope and in directive scope as well.

For details on each type of scope binding, please see excellent videos from egghead.io:

If you want to just pass strings into directive you might use @ binding:

In order to make attributes truly required, you can throw an exception from either link or compile function of directive when invalid values are provided or some values not provided at all.

Most complicated & binding, which allow you to provide method with parameters on parent scope to be called from directive:

Scoped parameters can not be used as attributes. I believe OP is asking for attributes.

There are 3 types of attribute scope binding: =, &, @. And you should use them appropriately.

This way your parameters will be treated as a string:

Very nice explanation, but 90% unrelated to the question !? This is not an answer !

Will create two-way binding between directive's scope properties and parent scope properties:

and chart.html

and markup

Note
Rectangle 27 0

javascript How to make directives look for two parameters?


<chart type="typeOne" legend="true"></chart>

<chart type="typeTwo" legend="true"></chart>

<chart type="typeThree" legend="true"></chart>
app.constant('chartTypes', ['typeOne', 'typeTwo']);
app.controller('typeOneController', ['$scope', '$attrs', function ($scope, $attrs) {

  var ctrl = this;

  ctrl.init = function () {
    console.log('We are initialised and ready to rock!');
  };

  $scope.someFunc = function () {
    console.log($scope, 'is the isolate scope defined in the directive');
  };

}]);
app.directive('chart', ['$controller', 'chartTypes', function ($controller, chartTypes) {
  return {

    restrict: 'E',

    scope: {
      'showGrouped': '='
    },

    controller: function ($scope, $element, $attrs) {

      if (chartTypes.indexOf($attrs.type) === -1) {

        throw new Error('Chart type ' + $attrs.type + ' is not supported at the moment');

      } else {

        return $controller($attrs.type + 'Controller', {
          $scope: $scope,
          $attrs: $attrs

        });
      }
    },

    link: function (scope, element, attrs, controller) {

      // Rock'n'roll...
      controller.init();

    }
  }
}]);
typeOne
var app = angular.module('app', []);

Register the constant to control which types we support

  • (Optional) A service to be aware of the currently active charts and what type they are.
  • A constant, to hold which types of charts you support throughout the application.
  • A named controller for each type of chart.
  • Chart typeThree should throw an error stating that the passed in chartType is not currently supported.
  • Chart typeTwo should throw an error stating that a Controller by that name could not be found (undefined).

Added jsFiddle showcasing the behaviour, albeit a bit simplified (not an isolated scope, no templateUrl): http://jsfiddle.net/ADukg/5416/

Another lesson to take home, is that anonymous functions as directive controllers are hard to test, in comparison to named controllers that are defined elsewhere, then injected into the directive. Separation is gold.

Edit 2: Updated the jsFiddle link, this one was with an isolated scope and hence the ng-click definition on the calling element does not fire off the isolated functions.

Edit 4: Added another jsFiddle, showcasing an isolate scope and a templateURL. More in line with what you are working with.

I'd make use of the following:

I'll see if I can't get a plunker or something of the sort uploaded throughout the day.

Let me know if this does the trick for you, or if you need a more in depth example of how to set it up.

Note: I stripped away the ngModel requirement from the directive for now to make it clearer how to build something like this. I'm not sure how you would get ngModel to play alongside this solution, but I'm sure you can figure that one out.. If not, I'd be happy to give it a try later on.

Now, this is not your conventional directive structure - but it's one I think is highly underused. The benefits of having your linking function be a controller, is that you can completely separate the $scope behaviour from the directive definition.

This could be built on further to include services and what not, everything can then be injected into your Controllers, on a per-chart basis (or into the directive definition, to have it be there for all the charts), giving you a ton of flexibility and ease of testing to boot.

This in turn allows us to unit test $scope behaviour for the directive itself, without the need to instantiate the directive and its DOM structure in our unit tests. Another added benefit is that you don't have to setup multiple directives for different chart types, we simply call for a controller (or, linking behaviour (if you will)) based on the chart type passed into the directive definition.

Note