TypeError:控制器功能不是功能

时间:2019-07-29 01:15:00

标签: angularjs controller directive

尝试使用具有链接功能的双模整流来理解AngularJS。我知道这是Angular的旧类型,但这是我们古老的项目所基于的。所以我的目标是创建一个事件日历。在指令级别,我有第四个参数,即控制器。该控制器包含当指令尝试调用时似乎无法识别的方法。我将日志放到控制器中,它已经被调用,但是使用其本机方法时无济于事。这是我从某处获得的演示:https://angular-ui.github.io/ui-calendar/

请注意,我实现日历的项目结构不同,它基于spring boot,并且所有有角度的东西都可以注入父js文件中。我在控制台日志中放置了指令和控制器,以确保我正在调用它,这似乎是,但是链接函数中第4个参数控制器内部的函数/方法不是。

HTML标签

 <div ui-calendar-event="uiConfig.calendar" class="span8 calendar" ng-model="eventSources"></div> 

指令:UiCalendarEvent

  define(['angular'],
        function(angular) {

        uiCalendarEvent =  function () {

                    return {
                        restrict : 'EA',
                        templateUrl: '/views/common/eventCalendarTemplate.html',
                        transclude: true,
                        scope : {
                            eventSources : '=ngModel',
                             calendarWatchEvent : '&'
                        },
                        controller : 'uiCalendarController',
                        link : function (scope, elm, attrs, controller) {
                            console.log("uiCalendar directive");
                            var sources = scope.eventSources;
                            var sourcesChanged = false;
                            var calendar;
                            var eventSourcesWatcher = controller.changeWatcher(sources, controller.sourceFingerprint);
                            var eventsWatcher = controller.changeWatcher(controller.allEvents, controller.eventFingerprint);
                            var options = null;

                            function getOptions () {
                                var calendarSettings = attrs.uiCalendar ? scope.$parent.$eval(attrs.uiCalendar) : {};
                                var fullCalendarConfig = controller.getFullCalendarConfig(calendarSettings, uiCalendarConfig);
                                var localeFullCalendarConfig = controller.getLocaleConfig(fullCalendarConfig);
                                angular.extend(localeFullCalendarConfig, fullCalendarConfig);
                                options = {
                                    eventSources : sources
                                };
                                angular.extend(options, localeFullCalendarConfig);
                                //remove calendars from options
                                options.calendars = null;

                                var options2 = {};
                                for (var o in options) {
                                    if (o !== 'eventSources') {
                                        options2[o] = options[o];
                                    }
                                }
                                return JSON.stringify(options2);
                            }

                            scope.destroyCalendar = function () {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar('destroy');
                                }
                                if (attrs.calendar) {
                                    calendar = uiCalendarConfig.calendars[attrs.calendar] = angular.element(elm).html('');
                                } else {
                                    calendar = angular.element(elm).html('');
                                }
                            };

                            scope.initCalendar = function () {
                                if (!calendar) {
                                    calendar = $(elm).html('');
                                }
                                calendar.fullCalendar(options);
                                if (attrs.calendar) {
                                    uiCalendarConfig.calendars[attrs.calendar] = calendar;
                                }
                            };

                            scope.$on('$destroy', function () {
                                scope.destroyCalendar();
                            });

                            eventSourcesWatcher.onAdded = function (source) {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar(options);
                                    if (attrs.calendar) {
                                        uiCalendarConfig.calendars[attrs.calendar] = calendar;
                                    }
                                    calendar.fullCalendar('addEventSource', source);
                                    sourcesChanged = true;
                                }
                            };

                            eventSourcesWatcher.onRemoved = function (source) {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar('removeEventSource', source);
                                    sourcesChanged = true;
                                }
                            };

                            eventSourcesWatcher.onChanged = function () {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar('refetchEvents');
                                    sourcesChanged = true;
                                }
                            };

                            eventsWatcher.onAdded = function (event) {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar('renderEvent', event, !!event.stick);
                                }
                            };

                            eventsWatcher.onRemoved = function (event) {
                                if (calendar && calendar.fullCalendar) {
                                    calendar.fullCalendar('removeEvents', event._id);
                                }
                            };

                            eventsWatcher.onChanged = function (event) {
                                if (calendar && calendar.fullCalendar) {
                                    var clientEvents = calendar.fullCalendar('clientEvents', event._id);
                                    for (var i = 0; i < clientEvents.length; i++) {
                                        var clientEvent = clientEvents[i];
                                        clientEvent = angular.extend(clientEvent, event);
                                        calendar.fullCalendar('updateEvent', clientEvent);
                                    }
                                }
                            };

                            eventSourcesWatcher.subscribe(scope);
                            eventsWatcher.subscribe(scope, function () {
                                if (sourcesChanged === true) {
                                    sourcesChanged = false;
                                    // return false to prevent onAdded/Removed/Changed handlers from firing in this case
                                    return false;
                                }
                            });

                            scope.$watch(getOptions, function (newValue, oldValue) {
                                if (newValue !== oldValue) {
                                    scope.destroyCalendar();
                                    scope.initCalendar();
                                } else if ((newValue && angular.isUndefined(calendar))) {
                                    scope.initCalendar();
                                }
                            });
                        }
                    };
                }



        uiCalendarEvent.$inject = ['uiCalendarConfig'];

        return uiCalendarEvent;
    });

Param Controller:UiCalendarController

define(['angular'],
function (angular) {

    uiCalendarController = function($scope, $locale){
        console.log("uiCalendarController");
        var sources = $scope.eventSources;
        var extraEventSignature = $scope.calendarWatchEvent ? $scope.calendarWatchEvent : angular.noop;

        var wrapFunctionWithScopeApply = function (functionToWrap) {
            return function () {
                // This may happen outside of angular context, so create one if outside.
                if ($scope.$root.$$phase) {
                    return functionToWrap.apply(this, arguments);
                }

                var args = arguments;
                var that = this;
                return $scope.$root.$apply(
                    function () {
                        return functionToWrap.apply(that, args);
                    }
                );
            };
        };

        var eventSerialId = 1;
        // @return {String} fingerprint of the event object and its properties
        eventFingerprint = function (e) {
            if (!e._id) {
                e._id = eventSerialId++;
            }

            var extraSignature = extraEventSignature({
                event : e
            }) || '';
            var start = moment.isMoment(e.start) ? e.start.unix() : (e.start ? moment(e.start).unix() : '');
            var end = moment.isMoment(e.end) ? e.end.unix() : (e.end ? moment(e.end).unix() : '');

            // This extracts all the information we need from the event. http://jsperf.com/angular-calendar-events-fingerprint/3
            return [e._id, e.id || '', e.title || '', e.url || '', start, end, e.allDay || '', e.className || '', extraSignature].join('');
        };

        var sourceSerialId = 1;
        var sourceEventsSerialId = 1;
        // @return {String} fingerprint of the source object and its events array
        sourceFingerprint = function (source) {
            var fp = '' + (source.__id || (source.__id = sourceSerialId++));
            var events = angular.isObject(source) && source.events;

            if (events) {
                fp = fp + '-' + (events.__id || (events.__id = sourceEventsSerialId++));
            }
            return fp;
        };

        // @return {Array} all events from all sources
        allEvents = function () {
            return Array.prototype.concat.apply(
                [],
                (sources || []).reduce(
                    function (previous, source) {
                        if (angular.isArray(source)) {
                            previous.push(source);
                        } else if (angular.isObject(source) && angular.isArray(source.events)) {
                            var extEvent = Object.keys(source).filter(
                                function (key) {
                                    return (key !== '_id' && key !== 'events');
                                }
                            );

                            source.events.forEach(
                                function (event) {
                                    angular.extend(event, extEvent);
                                }
                            );

                            previous.push(source.events);
                        }
                        return previous;
                    },
                    []
                )
            );
        };

        // Track changes in array of objects by assigning id tokens to each element and watching the scope for changes in the tokens
        // @param {Array|Function} arraySource array of objects to watch
        // @param tokenFn {Function} that returns the token for a given object
        // @return {Object}
        //  subscribe: function(scope, function(newTokens, oldTokens))
        //    called when source has changed. return false to prevent individual callbacks from firing
        //  onAdded/Removed/Changed:
        //    when set to a callback, called each item where a respective change is detected
        changeWatcher = function (arraySource, tokenFn) {
            var self;

            var getTokens = function () {
                return ((angular.isFunction(arraySource) ? arraySource() : arraySource) || []).reduce(
                    function (rslt, el) {
                        var token = tokenFn(el);
                        map[token] = el;
                        rslt.push(token);
                        return rslt;
                    },
                    []
                );
            };

            // @param {Array} a
            // @param {Array} b
            // @return {Array} elements in that are in a but not in b
            // @example
            //  subtractAsSets([6, 100, 4, 5], [4, 5, 7]) // [6, 100]
            var subtractAsSets = function (a, b) {
                var obj = (b || []).reduce(
                    function (rslt, val) {
                        rslt[val] = true;
                        return rslt;
                    },
                    Object.create(null)
                );
                return (a || []).filter(
                    function (val) {
                        return !obj[val];
                    }
                );
            };

            // Map objects to tokens and vice-versa
            var map = {};

            // Compare newTokens to oldTokens and call onAdded, onRemoved, and onChanged handlers for each affected event respectively.
            var applyChanges = function (newTokens, oldTokens) {
                var i;
                var token;
                var replacedTokens = {};
                var removedTokens = subtractAsSets(oldTokens, newTokens);
                for (i = 0; i < removedTokens.length; i++) {
                    var removedToken = removedTokens[i];
                    var el = map[removedToken];
                    delete map[removedToken];
                    var newToken = tokenFn(el);
                    // if the element wasn't removed but simply got a new token, its old token will be different from the current one
                    if (newToken === removedToken) {
                        self.onRemoved(el);
                    } else {
                        replacedTokens[newToken] = removedToken;
                        self.onChanged(el);
                    }
                }

                var addedTokens = subtractAsSets(newTokens, oldTokens);
                for (i = 0; i < addedTokens.length; i++) {
                    token = addedTokens[i];
                    if (!replacedTokens[token]) {
                        self.onAdded(map[token]);
                    }
                }
            };

            self = {
                subscribe : function (scope, onArrayChanged) {
                    scope.$watch(getTokens, function (newTokens, oldTokens) {
                        var notify = !(onArrayChanged && onArrayChanged(newTokens, oldTokens) === false);
                        if (notify) {
                            applyChanges(newTokens, oldTokens);
                        }
                    }, true);
                },
                onAdded : angular.noop,
                onChanged : angular.noop,
                onRemoved : angular.noop
            };
            return self;
        };

        getFullCalendarConfig = function (calendarSettings, uiCalendarConfig) {
            var config = {};

            angular.extend(config, uiCalendarConfig);
            angular.extend(config, calendarSettings);

            angular.forEach(config, function (value, key) {
                if (typeof value === 'function') {
                    config[key] = wrapFunctionWithScopeApply(config[key]);
                }
            });

            return config;
        };

        getLocaleConfig = function (fullCalendarConfig) {
            if (!fullCalendarConfig.lang && !fullCalendarConfig.locale || fullCalendarConfig.useNgLocale) {
                // Configure to use locale names by default
                var tValues = function (data) {
                    // convert {0: "Jan", 1: "Feb", ...} to ["Jan", "Feb", ...]
                    return (Object.keys(data) || []).reduce(
                        function (rslt, el) {
                            rslt.push(data[el]);
                            return rslt;
                        },
                        []
                    );
                };

                var dtf = $locale.DATETIME_FORMATS;
                return {
                    monthNames : tValues(dtf.MONTH),
                    monthNamesShort : tValues(dtf.SHORTMONTH),
                    dayNames : tValues(dtf.DAY),
                    dayNamesShort : tValues(dtf.SHORTDAY)
                };
            }

            return {};
        };
    }//end controller function
    uiCalendarController.$inject=['$scope','$locale'];
    return uiCalendarController;
});

EventCalendarController

define(['angular'],
        function(angular){
    eventCalendarController = function($scope, $compile, $timeout, uiCalendarConfig) {
        console.log("eventCalendarController");
    var date = new Date();
    var d = date.getDate();
    var m = date.getMonth();
    var y = date.getFullYear();

    $scope.changeTo = 'Hungarian';
    /* event source that pulls from google.com */
    $scope.eventSource = {
            url: "http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
            className: 'gcal-event',           // an option!
            currentTimezone: 'America/Chicago' // an option!
    };
    /* event source that contains custom events on the scope */
    $scope.events = [
      {title: 'All Day Event',start: new Date(y, m, 1)},
      {title: 'Long Event',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)},
      {id: 999,title: 'Repeating Event',start: new Date(y, m, d - 3, 16, 0),allDay: false},
      {id: 999,title: 'Repeating Event',start: new Date(y, m, d + 4, 16, 0),allDay: false},
      {title: 'Birthday Party',start: new Date(y, m, d + 1, 19, 0),end: new Date(y, m, d + 1, 22, 30),allDay: false},
      {title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}
    ];
    /* event source that calls a function on every view switch */
    $scope.eventsF = function (start, end, timezone, callback) {
      var s = new Date(start).getTime() / 1000;
      var e = new Date(end).getTime() / 1000;
      var m = new Date(start).getMonth();
      var events = [{title: 'Feed Me ' + m,start: s + (50000),end: s + (100000),allDay: false, className: ['customFeed']}];
      callback(events);
    };

    $scope.calEventsExt = {
       color: '#f00',
       textColor: 'yellow',
       events: [
          {type:'party',title: 'Lunch',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
          {type:'party',title: 'Lunch 2',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
          {type:'party',title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}
        ]
    };
    /* alert on eventClick */
    $scope.alertOnEventClick = function( date, jsEvent, view){
        $scope.alertMessage = (date.title + ' was clicked ');
    };
    /* alert on Drop */
     $scope.alertOnDrop = function(event, delta, revertFunc, jsEvent, ui, view){
       $scope.alertMessage = ('Event Dropped to make dayDelta ' + delta);
    };
    /* alert on Resize */
    $scope.alertOnResize = function(event, delta, revertFunc, jsEvent, ui, view ){
       $scope.alertMessage = ('Event Resized to make dayDelta ' + delta);
    };
    /* add and removes an event source of choice */
    $scope.addRemoveEventSource = function(sources,source) {
      var canAdd = 0;
      angular.forEach(sources,function(value, key){
        if(sources[key] === source){
          sources.splice(key,1);
          canAdd = 1;
        }
      });
      if(canAdd === 0){
        sources.push(source);
      }
    };
    /* add custom event*/
    $scope.addEvent = function() {
      $scope.events.push({
        title: 'Open Sesame',
        start: new Date(y, m, 28),
        end: new Date(y, m, 29),
        className: ['openSesame']
      });
    };
    /* remove event */
    $scope.remove = function(index) {
      $scope.events.splice(index,1);
    };
    /* Change View */
    $scope.changeView = function(view,calendar) {
      uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
    };
    /* Change View */
    $scope.renderCalendar = function(calendar) {
      $timeout(function() {
        if(uiCalendarConfig.calendars[calendar]){
          uiCalendarConfig.calendars[calendar].fullCalendar('render');
        }
      });
    };
     /* Render Tooltip */
    $scope.eventRender = function( event, element, view ) {
        element.attr({'tooltip': event.title,
                      'tooltip-append-to-body': true});
        $compile(element)($scope);
    };
    /* config object */
    $scope.uiConfig = {
      calendar:{
        height: 450,
        editable: true,
        header:{
          left: 'title',
          center: '',
          right: 'today prev,next'
        },
        eventClick: $scope.alertOnEventClick,
        eventDrop: $scope.alertOnDrop,
        eventResize: $scope.alertOnResize,
        eventRender: $scope.eventRender
      }
    };

    $scope.changeLang = function() {
      if($scope.changeTo === 'Hungarian'){
        $scope.uiConfig.calendar.dayNames = ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat"];
        $scope.uiConfig.calendar.dayNamesShort = ["Vas", "Hét", "Kedd", "Sze", "Csüt", "Pén", "Szo"];
        $scope.changeTo= 'English';
      } else {
        $scope.uiConfig.calendar.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
        $scope.uiConfig.calendar.dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        $scope.changeTo = 'Hungarian';
      }
    };
    /* event sources array*/
    $scope.eventSources = [$scope.events, $scope.eventSource, $scope.eventsF];
    $scope.eventSources2 = [$scope.calEventsExt, $scope.eventsF, $scope.events];


}
    eventCalendarController.$inject=['$scope', '$compile', '$timeout'];
    return eventCalendarController;

});

1 个答案:

答案 0 :(得分:0)

为回答我自己的问题而道歉,发现要在控制器参数中访问的功能应带有“ this”。在每个函数名称上。

<div class="flex-col">
  <input type="text" class="coupon input-res">
  <button class="coupon-btn">Apply</button>
</div>