Ziony
Ziony

Reputation: 113

Calling a controller function from within a directive

I have a datepicker directive that has in input box before it (thus an input group). When the datepicker icon is clicked, a drop down calendar is shown whose selected date shows up on the aforementioned textbox. This directive is wihin a controller that has updateDate function. As you might have guessed, I want this to fire whenever a date is selected. Here is my code:

For the HTML

<div ng-controller="DateController as ctrl">
<div class="row">
    <label class="col-md-12 label-question header-title main-question">
        What is your Event Date?
    </label>
    <div class="spacer40"></div>                    
</div>//row

<div id="eventDate" class="form-group">

    <div class="input-group" gf-option-date-active >

        <!-- RADIO AND LABEL -->
         <div class="row">
            <div class="col-md-12 radio-label">
                <!--<label for="dateType" class="label-question"></label>-->
                <input id="startAndEndDate" class="radio-button" 
                       type="radio" 
                       name="dateType" 
                       value="{{ ctrl.model.dateTypes.collection[1].id }}" 
                       ng-model="ctrl.model.selectedDateType" 
                       ng-change="ctrl.updateDate()"
                       />

                <label for="startAndEndDate" name="startandend" class="label-question">
                Event occurs in a single day</label>
            </div>

            <div class="col-md-6">
                <input type="text"

                       ng-model-onblur

                       gf-option-date-active 
                       data-alti-datepicker 
                       ng-model="ctrl.model.singleDate" 
                       id="startAndEndDate" 
                       ng-change="ctrl.updateDate()"/>
            </div>                                  
        </div>

</div>//input-gorup div
</div>//event-date div
</div>// controller div

For the Controller:

(function(ctrl){
    'use restrict';

    function DateController(DateService){
        var vm = this;
        var __dateSvc = DateService;
        vm.model = DateService.model;
        vm.updateDate = DateService.updateDate();
    };

    ctrl.controller('DateController', DateController);

}(angular.module('dates.controller', [])));

For the Directive:

(function(dir){
    'use strict';

    function DatePicker(){
            var linkFunc= function(scope, elem, attrs, ngModelCtrl) {
                var id = attrs.id;
                scope[id+'open'] = function ($event) {

                    $event.preventDefault();
                    $event.stopPropagation();

                    scope[id+'opened'] = true;
                };
            };

            return {
                restrict: 'AE',
                replace: true,
                scope:true,
                compile: function (element, attrs) {
                    var html = '<p class="input-group">'+
                            '<input id="' + attrs.id + '" type="text" class="form-control date-input" datepicker-popup="dd.MM.yyyy" ng-model="'+attrs.ngModel+'" is-open="'+attrs.id+'opened" ng-required="true" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close"/>'
                            +'<span class="input-group-btn">'
                            +    '<button id="' +  attrs.id  + '" type="button" class="btn btn-default date-button" ng-click="'+attrs.id+'open($event)"><img calendar-icon src="/assets/images/questions/calendar.png"</button></span></p>';
                    var e = angular.element(html);
                    element.replaceWith(e);
                    });
                    return linkFunc;
                }
            }
    };

  dir.directive('altiDatepicker', DatePicker);

}(angular.module('dates.directive', [])));

I'm relatively new to angular and thus am still stumped by these.

Upvotes: 0

Views: 447

Answers (2)

mukade
mukade

Reputation: 660

You can declare a private controller inside a directive in the DDO (Directive Definition Object) and you also can require the controllers from another directives.

Your HTML will be:

<div directiveA value="true">
    <div directiveb></div>
</div>

Your JS is going to be like:

var app = angular.module('foo'); 

app.directive('directiveA', function(){

    var ctrl = ['$scope', function ($scope) {
    this.getSomething = function() {
        return $scope.value;
    };
  }];

    return { // returning the DDO
        restric: 'EA',
        controller: ctrl,
        scope: {
            value: '='
        }
    }
});

app.directive('directiveB', function(){

    var ctrl = ['$scope', function ($scope, directiveActrl) {
        $scope.value = directiveActrl.getSomething();
    };

    return { // returning the DDO
        restric: 'EA',
        require: '^directiveA'
        controller: ctrl,
        template: '<p>{{value}}</p>'
    }
})

About using controllers inside directives: http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-6-using-controllers

About requiring directive controllers: http://www.chroder.com/2014/02/01/using-ngmodelcontroller-with-custom-directives/

Upvotes: 1

Mike
Mike

Reputation: 447

You can pass to your directive some angular models from parent node(e.g. parent Controller) You can add this code to your directive:

scope: {
      modelToPass: '='
    },

Then, in your template where you create your directive, follow the example:

 <my-directive modelToPass="modelFromParentController"></my-directive >

Now you can use this model inside your directive, you can add event listeners, watchers etc.

Upvotes: 0

Related Questions