从指令中调用控制器函数

时间:2015-01-27 12:46:56

标签: angularjs controller directive

我有一个datepicker指令,它在输入框之前(因此是一个输入组)。单击日期选择器图标时,将显示一个下拉日历,其选定日期显示在上述文本框中。该指令是具有 updateDate 功能的控制器。正如您可能已经猜到的那样,我希望每当选择日期时都会触发此操作。这是我的代码:

对于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

对于控制器:

(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', [])));

对于指令:

(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', [])));

我对角度相对较新,因此仍然被这些感到难过。

2 个答案:

答案 0 :(得分:1)

您可以在DDO(指令定义对象)中的指令内声明私有控制器,您也可以从其他指令中要求控制器。

您的HTML将是:

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

你的JS将会像:

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>'
    }
})

关于在指令中使用控制器:http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-6-using-controllers

关于要求指令控制器: http://www.chroder.com/2014/02/01/using-ngmodelcontroller-with-custom-directives/

答案 1 :(得分:0)

您可以从父节点(例如父控制器)向您的指令传递一些角度模型。您可以将此代码添加到您的指令中:

scope: {
      modelToPass: '='
    },

然后,在您创建指令的模板中,请按照示例进行操作:

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

现在你可以在你的指令中使用这个模型,你可以添加事件监听器,观察者等。