Question

J'ai cherché un cueilleur de rendez-vous approprié pour AngularJS et je me suis installé sur l'utilisation de pickadate.js

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

en raison de sa belle interface utilisateur mobile ainsi que d'une directive personnalisée pour permettre l'intégration angulaire, comme indiqué dans cet article de blog

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

Je voulais étendre la directive dans le billet de blog ci-dessus avec un événement pour appeler une fonction dans mon contrôleur lorsque la valeur change.Le code complet de la directive étendue est affiché ci-dessous

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

Je peux maintenant utiliser cette directive avec un événement de changement comme indiqué ci-dessous dans mon HTML

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

Cela fonctionne mais l'événement OnChange est déclenché plusieurs fois pour un seul changement.Avez-vous une idée sur la façon dont je peux le faire tirer une seule fois ?J'ai créé un plunker pour démontrer le problème

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

Cliquez sur le champ de texte et sélectionnez une date.Vous verrez que la variable du compteur est mise à jour plusieurs fois pour un seul changement de date.

Était-ce utile?

La solution

Comme @miqid a suggéré de lier une fonction entre une directive et une utilisation de contrôleur '&' ('=' doit être utilisé uniquement pour lier les variables de portée entre la directive et le contrôleur.)

Il y a également une modification supplémentaire à apporter à votre code actuel.La fonction scope.change dans updateValue() n'est pas exécuté car il a été référencé comme scope.change.Cela doit être changé en scope.change().

J'ai bifurqué votre plunker et l'ai modifié pour corriger les modifications ci-dessus.

Plunker de travail fixe : http://plnkr.co/edit/oEpOxE21dXre28FpKoMc?p=preview

Le compteur n'est mis à jour qu'une seule fois pour changer.Faites-moi savoir si cela aide.

Autres conseils

Vous avez lié change à l'intérieur de ton pick-a-date directive utilisant '=' au lieu de '&'.

Cette dernière liaison de portée d'isolement est recommandée pour les expressions telles que les fonctions de rappel.

Conseils pertinents de la documentation AngularJS sur directive:

Meilleur entrainement: utiliser &attr dans l'option scope lorsque vous souhaitez que votre directive expose une API pour la liaison aux comportements.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top