Casey Flynn
Casey Flynn

Reputation: 14048

AngularJS create directive & pass in array of key/value pairs for buttons that relate to actions in parent controller

I'm trying to make a directive widget in AngularJS and I would like to pass in an array of name,action k/v pairs to represent buttons that will trigger actions on the parent controller.

What I've tried so far:

<div data-collapse-widget data-title="Templates" data-widget-themis="false" data-color="grey" data-buttons="[new:'test']">

^The start of my directive in HTML

My javascript (coffeescript)

Module.directive 'collapseWidget', () ->
      directive =
        restrict:   'A'
        transclude: true
        template:   viewCollapseWidget
        scope:
          title:        '@title'
          widgetThemis: '@widgetThemis'
          color:        '@color'
          buttons:      '&buttons'

        replace: true
        compile: (element, attrs, transclusionFunc) ->
          (scope, iterStartElement, attrs) ->

            scope.collapsed = false
            scope.toggle = () ->
              scope.collapsed = !scope.collapsed

            origElem   = transclusionFunc scope
            content    = origElem.text()
            scope.orig = content
            #scope.obj = my_custom_parsing(content)
            scope.obj  = content

But obviously this does not work. Anyone know how I might do this?

Upvotes: 2

Views: 5066

Answers (1)

Ryan Q
Ryan Q

Reputation: 10683

I can't see what viewCollapseWidget is from the post, but the basic idea is to setup the model in the "parent' controller to contain the buttons object you have in your

<div data-collapse-widget>

So you can simply pass the model value to the directive and have the button execute the passed function later. This method also allows the directive scope to be isolated rather than trying to dirty the parent scope. I've posted a JsFiddle of the following:

Your view might look something like this with the directive inserted:

<div ng-controller="ParentCtrl">
   <div collapse-widget 
        title="Show / Collapse" 
        buttons="model.buttons"></div>
</div>

The controller logic and directive might look something like this:

angular.module('main', [])
.controller("ParentCtrl", ['$scope', function( $scope ){

    $scope.doSomething = function(){
        alert('do something called from parent');
    }
    $scope.doSomethingElse = function(){
        alert('do something else called from parent ');
    }

    $scope.model ={
        buttons: {
           'Test Button':     $scope.doSomething, 
           'Another Button':  $scope.doSomethingElse
        }
    }
}])

.directive("collapseWidget", function factory() {
   return {
     template: '<div ng-init="collapsed=true">'+
                 '<h2 ng-click="collapsed= {true: false, false: true}[collapsed]">{{title}}</h2>'+
                 '<button ng-hide="collapsed" '+
                        'ng-repeat="(name, fn) in buttons" ng-click="fn()">{{name}}</button>'+
               '</div>',
    replace: true,
    restrict: 'A',
    scope: {
      title: "@",
      buttons: "="
    },
    link: function postLink( scope, element, attrs ) {
      //do something else here
    }
  };
});

Upvotes: 2

Related Questions