0

I have a button in my directive that is supposed to open a configuration ngDialog.

Here is my code for theme.html directive:

<div class="col-lg-3 col-md-6">
    <div class="panel panel-{{colour}}">
        <div class="panel-heading">
            <div class="row">
                <div class="col-xs-3">
                    <i class="fa fa-{{type}} fa-5x"></i>
                </div>
                <div class="col-xs-9 text-right">
                    <div class="huge">{{name}}</div>
                    <div>{{comments}}</div>
                </div>
            </div>
        </div>
        <div class="panel-footer">
            <div class="ngdialog-buttons btn-toolbar">
                <button type="button" ng-dialog-controller="MainCtrl" class="ngdialog-button btn btn-primary pull-right" ng-click="openConfigWindow('theme')">Settings</button>
            </div>
            <div class="clearfix"></div>
        </div>
    </div>
</div>

theme.js

angular.module('adminApp')
    .directive('theme',function() {
        return {
            templateUrl:'scripts/directives/theme/theme.html',
            restrict:'E',
            replace:true,
            scope: {
                'model': '=',
                'comments': '@',
                'name': '@',
                'colour': '@',
                'details':'@',
                'type':'@',
                'goto':'@',
                'status':'@'
                /*hooking this event invokes the ngClick, but not on the button*/
                //eventHandler: '&ngClick'
            }
        }
    });

Here is how theme directive is used in html:

<div class="panel-body" data-ng-controller="MainCtrl">
<theme name="test" comments="New comments!" colour="info" type="sample" status="Deactivate"></theme>
</div>

main.js contains the MainCtrl controller:

angular.module('adminApp')
  .controller('MainCtrl', function($scope,$position,$rootScope, ngDialog) {

      $scope.openConfigWindow = function (themeName) {
        $rootScope.theme = themeName;
        ngDialog.open({
          template: '/views/configPopup.html',
          controller: 'InsideCtrl',
          className: 'ngdialog-theme-default dialogDimension',
          closeByDocument: false
        });
      };
  })

openConfigWindow is not invoked, how should I bind ng-click to the button inside my theme directive?

faizanjehangir
  • 2,771
  • 6
  • 45
  • 83

3 Answers3

1

openConfigWindow needs to be exposed in the link function of the directive instead of the containing scope. The issue is that your directive has an isolated scope and so cannot see its parent's model.

Something like:

link: function (scope, element, attrs) {   
      scope.openConfigWindow = function() {} 
}

Also, I am not so familiar with ngDialog, but using the angular-ui modal (which I know is very similar to ngDialog) you can pass a scope into your modal by specifying the scope parameter on modal instantiation. Passing info through $rootScope is not a good idea.

pQuestions123
  • 4,471
  • 6
  • 28
  • 59
1

On your directive you need to add the callback (you almost had it but it was more like an event handler than how NG typically does it). In order to pass parameters back to the callback expression where the directive is implemented you might want to read more here - Can an angular directive pass arguments to functions in expressions specified in the directive's attributes?

directive

angular.module('adminApp')
.directive('theme',function() {
    return {
        templateUrl:'scripts/directives/theme/theme.html',
        restrict:'E',
        replace:true,
        link: function( $scope, elem, attrs){
           $scope.openRqst = function(theme){
              $scope.openConfig({theme:theme}) //notice how I'm passing the theme param to the callback.
           }
        },
        scope: {
            'model': '=',
            'comments': '@',
            'name': '@',
            'colour': '@',
            'details':'@',
            'type':'@',
            'goto':'@',
            'status':'@',
            'openConfig': '&'
        }
    }
});

directive template's triggering button

<button type="button" ng-dialog-controller="MainCtrl" class="ngdialog-button btn btn-primary pull-right" 
        ng-click="openRqst('theme')">Settings</button>

implementation

<theme name="test" comments="New comments!" colour="info" type="sample" status="Deactivate" open-config="openConfigWindow(theme)"></theme>
Community
  • 1
  • 1
jusopi
  • 6,791
  • 2
  • 33
  • 44
  • I need to call `openConfigWindow` on button click inside the directive, not on the directive.. – faizanjehangir Sep 10 '15 at 15:33
  • 1
    you can't really do that because you've created an isolate scope. Meaning that the controller's methods aren't inherited by the directive's scope. So you use the isolate scope's callback syntax along with passing the parameter back so that the callback then calls the controller's method with the *theme* – jusopi Sep 10 '15 at 15:36
  • Thank you for the clarification, clean implementation on the `callback`. Is it possible to pass selected theme's `scope.name` in the `openRqst` function? – faizanjehangir Sep 10 '15 at 15:48
  • if `scope` is the directive's scope, then yes. You'd just say something like `openRqst( name )` on the directive template. Is that what you mean? I'm not entirely sure what the end result you're trying to accomplish is in terms of making this a *component*. I'd be more inclined to set a directive attribute called theme where you implement it and let the callback pull that from the directive's scope. – jusopi Sep 10 '15 at 19:34
0

I never heard of such thing as ng-dialog-controller, to bind a controller to your directive use the controller option, so ..

angular.module('adminApp')
   .directive('theme',function() {
     return {
       templateUrl:'scripts/directives/theme/theme.html',
       restrict:'E',
       replace:true,
       controller: 'MainCtrl',
       .............
       .........

    }
  }

});

Frederico Jesus
  • 649
  • 6
  • 14