将ajax数据从Controller传递给指令

时间:2016-03-12 12:47:46

标签: javascript jquery angularjs ajax

嘿,我已经建立了某种日期选择器+模态弹出窗口。 我希望系统以下列方式运行,用户选择2个日期:开始日期和结束日期,这定义了范围。然后用户单击GO按钮,Go按钮然后对服务器进行某种ajax调用并检索需要呈现的数据。 Go按钮是指令模板的一部分,现在我有几个问题:

  1. 我应该在哪里拨打ajax电话?在指令内或控制器中?

  2. 如果我在控制器内部进行ajax调用,我应该如何快速传递数据,这样当我点击GO按钮然后我会在开始弹出模式中看到数据?

  3. 我有什么选择将ajax数据从控制器传递到指令?

  4. enter image description here

    我附上以下指令代码,请将集合变量看作需要包含需要预先存储的ajax数据的变量。

    angular.module('directives', [])
        .directive('datepicker', ['$timeout', function ($timeout) {
            // Runs during compile
            return {
                scope: {
                    id: '@',
                    "class": '@',
                    onSelect: "&",
                    onSelectStartDate: '&',
                    onSelectEndDate: '&',
                    onSelectGoMode: '&',
                    collection: '=' // ajax data
                },
                restrict: 'E',
                template: '<div id="{{id}}" class="{{class}}">' +
                        '<div id="date-start-wrapper" class="date-wrapper">' +
                            '<label for="datepicker-start" class="datepicker-lbl">From:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-start" type="date"  placeholder="Select date" />' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>' +
                        '<div id="date-end-wrapper" class="date-wrapper">' +
                            '<label for="datepicker-end" class="datepicker-lbl">To:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-end" type="date" placeholder="Select date" />' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>' +
                        '<button id="GoBtn" class="btn btn-primary btn-md" >GO</button>' +
                        '<div id="blackout"></div>'+
                            '<div id="popup">'+
                                '<span class="close"></span>' +
                                '<h2>Enter Content</h2>' +
                                '<span>{{collection}}</span>'+
                                '<button id="okbtn" class="btn btn-success btn-md" >ok</button>' +
                                '<button id="cancelbtn" class="btn btn-danger btn-md" >cancel</button>' +
                            '</div>' +
                        '</div>'
                            ,
                replace: true,
                link: function ($scope, iElm, iAttrs, controller) {
                    console.log('directive iAttrs', iAttrs);
                    var Gobtn = iElm.find('button');
                    $scope.selectStartDate = function (time) {
                        if (angular.isFunction($scope.onSelectStartDate())) {
                            $scope.onSelectStartDate()(time);
                        }
                    }
                    $scope.selectEndDate = function (time) {
                        if (angular.isFunction($scope.onSelectEndDate())) {
                            $scope.onSelectEndDate()(time);
                        }
                    }
                    //define blackout and close click callbacks.
                    $("#blackout, .close").click(function () {
                        $("#blackout").removeClass("visable");
                        $("#popup").removeClass("visable");
                    });
    
                    Gobtn.click(function () {
                        console.log('$scope.onSelectGoMode()', $scope.onSelectGoMode());
                        if (angular.isFunction($scope.onSelectGoMode())) {
                            $scope.onSelectGoMode()();
                        }
                        $("#blackout").addClass("visable");
                        $("#popup").addClass("visable");
                    });
    
                    var actions = [$scope.selectStartDate, $scope.selectEndDate];
                    $(".date-wrapper").each(function (index) {
                        console.log('directive index', index);
                        console.log('actions:', actions);
                        $input = $(this).find('input');
                        $btn = $(this).find('.calendar');
    
                        console.log('input', $input[0]);
                        console.log('btn', $btn[0]);
                        var counter = 0;
                        var updateTime = $scope.selectDate;
    
                        $input.attr('type', 'text');
                        var pickerStart = new Pikaday({
                            field: $input[0],
                            trigger: $btn[0],
                            container: $(this)[0],
                            format: 'DD/MM/YYYY',
                            firstDay: 1,
                            onSelect: actions[index]
                        });
                        $btn.show();
                        counter++;
                    });
    
                }
            };
        }]);
    

1 个答案:

答案 0 :(得分:1)

由于您有一个独立的日期选择器和范围选择器以及一个操作按钮,您可以继续在指令功能中进行ajax调用。由于您的指令将为您的模板创建一个新的范围,所有您的数据将在该范围内随时可用。

此外,我建议将指令配置为接受URL作为参数以及其他参数,如id,collection ..etc。所以你可以重复使用它。

至于模态,你可以在指令本身中注入模态服务

angular.module('directives', [])
.directive('datepicker', ['$timeout','modalService', function ($timeout,modalService) {
    // Runs during compile
    return {
        scope: { ........
        .............
        .............


Gobtn.click(function () {
                .............
                 ..............

                //Call modal service here...
                 modalService.showModel(); // just an sample...call replace with you modal implementation please
            });
        ..............

如果您想与父控制器进行数据通信,您可以使用指令中的$emit(myEvent, args); ....

然后像你这样在控制器中捕获emit消息......

angular.module('eventExample', [])
  .controller('EventController', ['$scope', function($scope) {
      $scope.count = 0;
      $scope.$on('MyEvent',  function(event, args) {
         var anyThing = args.any;
          // do what you want to do
         });
  }]);

您还可以使用targetScope和currentScope添加要侦听的特定范围的发射或广播事件。参考this