Domanda

Ho cercato un raccoglitore di date adatto per AngularJs e sistemato sull'uso pickadate.js

http://amsul.ca/pickadate.js/

A causa del suo bell'interfaccia utente mobile insieme a una direttiva personalizzata per consentire l'integrazione angolare come mostrato in questo post del blog

http://www.codinginsight.com/angularjs-and-pickadate/

Volevo estendere la direttiva nel post del blog sopra con un evento per chiamare una funzione nel mio controller quando il valore cambia. Il codice completo per la direttiva estesa è mostrata sotto

angular.module('plunker').directive('pickADate', function () {
    return {
        restrict: "A",
        scope: {
            pickADate: '=',
            minDate: '=',
            maxDate: '=',
            change: '='
        },
        link: function (scope, element, attrs) {
            element.pickadate({
                onSet: function (e) {
                    if (scope.$$phase || scope.$root.$$phase) // we are coming from $watch or link setup
                        return;
                    var select = element.pickadate('picker').get('select'); // selected date
                    scope.$apply(function () {
                        if (e.hasOwnProperty('clear')) {
                            scope.pickADate = null;
                            return;
                        }
                        if (!scope.pickADate)
                            scope.pickADate = new Date(0);
                        scope.pickADate.setYear(select.obj.getFullYear());
                        // Interesting: getYear returns only since 1900. Use getFullYear instead.
                        // It took me half a day to figure that our. Ironically setYear()
                        // (not setFullYear, duh) accepts the actual year A.D.
                        // So as I got the $#%^ 114 and set it, guess what, I was transported to ancient Rome 114 A.D.
                        // That's it I'm done being a programmer, I'd rather go serve Emperor Trajan as a sex slave.
                        scope.pickADate.setMonth(select.obj.getMonth());
                        scope.pickADate.setDate(select.obj.getDate());
                    });
                },
                onClose: function () {
                    element.blur();
                }
            });
            function updateValue(newValue) {
                if (newValue) {
                    scope.pickADate = (newValue instanceof Date) ? newValue : new Date(newValue);
                    // needs to be in milliseconds
                    element.pickadate('picker').set('select', scope.pickADate.getTime());
                } else {
                    element.pickadate('picker').clear();
                    scope.pickADate = null;
                }
            }
            updateValue(scope.pickADate);
            element.pickadate('picker').set('min', scope.minDate ? scope.minDate : false);
            element.pickadate('picker').set('max', scope.maxDate ? scope.maxDate : false);
            scope.$watch('pickADate', function (newValue, oldValue) {
                if (newValue == oldValue)
                    return;
                updateValue(newValue);

                // call change function
                scope.change;
            }, true);
            scope.$watch('minDate', function (newValue, oldValue) {
                element.pickadate('picker').set('min', newValue ? newValue : false);
            }, true);
            scope.$watch('maxDate', function (newValue, oldValue) {
                element.pickadate('picker').set('max', newValue ? newValue : false);
            }, true);
        }
    };
});
.

Posso ora utilizzare questa direttiva con Modifica evento come mostrato di seguito nel mio HTML

<input type="text" pick-a-date="curDate" change="onChange()" />
.

funziona ma l'evento di onchange viene licenziato più volte per un singolo cambiamento. Qualche idea su come posso farcela per sparare solo una volta? Ho creato un pinkeer per dimostrare il problema

http://plnkr.co/edit/3ncaaknd4gpeljxhwuyv

Fare clic sul campo di testo e selezionare una data. Vedrete la variabile contatore viene aggiornata più volte per un cambio singolo data.

È stato utile?

Soluzione

AS @MIQID ha suggerito di assistere a una funzione tra la direttiva e un controller utilizzare '&' ('=' deve essere utilizzato solo per le variabili di ambito vincolante tra Direttiva e Controller.)

Inoltre c'è un altro cambiamento che deve essere fatto al tuo codice corrente.La funzione Scope.Change in updateValue() non viene eseguita in quanto è stata referenziata come scope.Change.Questo deve essere cambiato in scope.change().

Ho biforcuto il blocker e lo ha modificato per risolvere le modifiche sopra indicate.

Plunker di lavoro fisso: http://plnkr.co/edit/oepoxe21dxre28fpkomc?p=preview

Il contatore viene aggiornato solo una volta per un cambiamento.Fammi sapere se questo aiuta.

Altri suggerimenti

Hai legato change all'interno della direttiva pick-a-date utilizzando '=' anziché '&'.

Quest'ultimo legame dell'ambito dell'isolato è raccomandato per le espressioni come le funzioni di callback.

Consigli pertinenti della documentazione angolarejs su Direttive :

.

Best Practice: Utilizzare &attr nell'opzione Ambito quando si desidera che la tua direttiva esporre un'API per vincolante ai comportamenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top