2012-05-23 10 views
8

Aktualnie przesyłam dużą aplikację do aplikacji internetowej opartej na HTML5 - zacząłem budować aplikację w AngularJS i czerpać przyjemność z mocy frameworka AngularJS - mam jeden problem na mojej drodze obecnie:AngularJS - jQuery UI - kwestia wiążąca

Mam dyrektywę, która daje mi jQuery Datepicker, jednak wiązanie z modelem nie działa.

http://jsfiddle.net/9BRNf/

jestem chyba nieporozumienie drogę dyrektyw pracy i chcieliby zobaczyć, czy mogę załatać tę część mojego zrozumienia ram. Przeszedłem przez wiele przykładów (w tym projektu angularui na github, ale wciąż nie ma sensu, dlaczego wiązanie się nie dzieje).

wszelka pomoc będzie bardzo mile widziana.

+1

ok dobrze I wydaje się, że rozwiązanie - http : //jsfiddle.net/9BRNf/2/ - nadal chciałby wiedzieć, czy jest to poprawny/najlepszy sposób rozwiązania tego problemu. –

+0

Uważam, że onSelect datepicker nie jest potrzebny. Wartości zostaną już powiązane z modelem po zmianie selektora. – dj2

+0

@ dj2 to właśnie pomyślałem, ale sprawdź skrzypce w oryginalnej wiadomości - model nie jest wiążący. –

Odpowiedz

4

Po pierwsze, wspaniale jest, że używasz angularjs, jego słodkiej konstrukcji. Odgałęziony projekt został uruchomiony na chwilę, aby poradzić sobie z takimi rzeczami jak owijanie jquery-ui i tworzenie modułów UI.

Poniżej znajduje się link do implementacji Petera Bacona Darwina.

https://github.com/angular-ui/angular-ui/tree/master/modules/directives/date

--dan

+0

Dzięki Dan - co jest dziwne jest to, że faktycznie starał AngularUI dzień temu i dał dokładnie ten sam problem wiążący - Mam jednak próbował go ponownie teraz http://jsfiddle.net/9BRNf/6/ i działa idealnie. –

+0

To nie jest nadal współpracuje z najnowszymi angularjs (1.0.2 & Angular-UI (wziął ostatni dzisiaj) :-( –

+0

Sutikshan można umieścić skrzypce/plunkr opisując co nie działa? I dać więcej tła, jak przeglądarek używanych. przykładem dinesh pracuje bez zarzutu. I wiem, że istnieją pewne problemy są zgłaszane, ale to nie działa. –

2

kątowe-ui datepicker nie działa z Kątowymi 1.0.0, więc przepisałem go. Mój widełek daje możliwość ustawienia, jak data jest sformatowana wewnątrz wejścia i jak zostanie zapisany z powrotem do modelu.

Kod: https://gist.github.com/2967979 jsFiddle: http://jsfiddle.net/m8L8Y/8/ (Brakuje style jQuery UI, ale działa tak samo)


// Code inspired by angular-ui https://github.com/angular-ui/angular-ui/blob/master/modules/directives/date/src/date.js 
/* 
Features: 
* via the ui-date attribute: 
    * Ability to say how model is parsed into a date object 
    * Ability to say how input's value is parsed into a date object 
    * Ability to say how a date object is saved to the model 
    * Ability to say how a date object is displayed in the input 
* via the ui-date-picker attribute 
    * Ability to directly configure the jQuery-ui datepicker 
*/ 


angular.module('ui.directives', []) 
    .directive('uiDate', function() { 
     return { 
      require: '?ngModel', 
      //scope: {}, 
      link: function ($scope, element, attrs, ngModel) { 
       // Date Handling Functions 
       var dateHandler = $.extend({ model: {}, view: {} }, $scope.$eval(attrs.uiDate)); 

       // This will attempt to use preferredParser to parse a date. 
       function defaultDateParse(date, preferredParser) { 
        if (!preferredParser) 
         return new Date(date); 
        return preferredParser(date); 
       } 

       // This will attempt to use preferredFormatter to format a date, otherwise use 'mm/dd/yy'. 
       function defaultDateFormatter(date, preferredFormatter) { 
        if (!preferredFormatter) 
         preferredFormatter = "mm/dd/yy"; 

        if (typeof preferredFormatter == 'string') 
         return $.datepicker.formatDate(preferredFormatter, date); 
        else 
         return preferredFormatter(date); 
       } 

       // Functions for Parsing & Formatting on the Model & View 
       function parseDateFromModel(date) { 
        return defaultDateParse(date, dateHandler.model.parse) 
       } 
       function parseDateFromView(date) { 
        return defaultDateParse(date, dateHandler.view.parse) 
       } 
       function formatDateForModel(date) { 
        return defaultDateFormatter(date, dateHandler.model.format) 
       } 
       function formatDateForView(date) { 
        return defaultDateFormatter(date, dateHandler.view.format) 
       } 

       var defaultDateViewFormat = (
        typeof dateHandler.view.format == 'string' 
        ? dateHandler.view.format 
        : 'mm/dd/yy' 
       ) 

       // Initialize the jQuery-ui datePicker 
       var datePickerSettings = $.extend({ dateFormat: defaultDateViewFormat }, $scope.$eval(attrs.uiDatePicker)) 
       var oldOnSelect = datePickerSettings.onSelect; 
       datePickerSettings.onSelect = function (dateVal) { 
        $scope.$apply(function() { 
         element.focus().val(dateVal); 
         updateModel(); 
        }) 
        if (oldOnSelect) 
         oldOnSelect.apply(this, arguments) 
       } 

       element.datepicker(datePickerSettings); 

       if (ngModel) { 
        // Specify how UI should be updated 
        ngModel.$render = function() { 
         element.val(ngModel.$viewValue || ''); 
        }; 

        // Listen for change events to enable binding 
        element.bind('blur keyup change', function() { 
         $scope.$apply(updateModel); 
        }); 

        // Write data to the model 
        function updateModel() { 
         ngModel.$setViewValue(element.val()); 
        } 

        // Convert the model into a string value 
        ngModel.$formatters.push(function (v) { 
         if (v != "" && v != null) 
          return formatDateForView(parseDateFromModel(v)); 
         return null; 
        }); 

        // Convert the string value into the model 
        ngModel.$parsers.push(function (v) { 
         if (v != "" && v != null) 
          return formatDateForModel(parseDateFromView(v)) 
         return null; 
        }); 
       } 

      } 
     }; 
    }) 
+0

Zamieść swój kod do odpowiedzi, jak wtedy odpowiedź jest nadal przydatna, gdy Gist lub JSFiddle są niedostępne dla żadnego powodu. –

0

I właśnie przycięta kod, rzucić okiem na to: http://jsfiddle.net/YU5mV/

HTML

<input id="date1" value="1/1/1980" ng-model="fromDate" my-datepicker /> 
<input id="date2" value="1/1/1980" ng-model="toDate" my-datepicker /> 

JavaScript

angular.module('myApp.directives', []) 
    .directive('myDatepicker', function() { 
    return function(scope, element, attrs) {  

     element.datepicker({ 
     changeYear : true, 
     changeMonth : true, 
     appendText : '(yyyy-mm-dd)', 
     dateFormat : 'yy-mm-dd', 
      onSelect: function(dateText) {      
       var mdlAttr = $(this).attr('ng-model'); 
       scope[mdlAttr] = dateText;      
       scope.$apply();             
      }     
     }); 

    } 
    }); 
+3

Proszę wysłać kod do odpowiedzi, jak wtedy odpowiedź jest nadal użyteczny jeśli JSFiddle jest niedostępne z jakiejkolwiek przyczyny. –

2

podobne do praveepd (używając ich jako podstawy), ale będzie to wybór głęboki modelu.

http://jsfiddle.net/c8PMa/

var myApp = angular.module('myApp', ['myApp.directives']); 

function MainCtrl($scope) { 

    $scope.deepValue = { 
     fromDate: null, 
     toDate: null 
    } 

} 

angular.module('myApp.directives', []) 
    .directive('myDatepicker', function() { 
    return function(scope, element, attrs) {  

     element.datepicker({ 
     changeYear : true, 
     changeMonth : true, 
     appendText : '(yyyy-mm-dd)', 
     dateFormat : 'yy-mm-dd', 
       onSelect: function(dateText) {      
        var mdlAttr = $(this).attr('ng-model').split("."); 

        if (mdlAttr.length > 1) { 

         var objAttr = mdlAttr[mdlAttr.length-1]; 
         var s = scope[mdlAttr[0]]; 

         for (var i=0; i < mdlAttr.length-2; i++) { 
          s = s[mdlAttr[i]]; 
         } 

         s[objAttr] = dateText; 
        } else { 
         scope[mdlAttr[0]] = dateText; 
        } 

        scope.$apply(); 
       }     
     }); 

    } 
});​ 
+0

Aby poprawić jakość swojego posta proszę podać jak/dlaczego Twój post rozwiąże problem. –

0

Stare pytanie, ale było to pierwsze trafienie dla mnie w google dla tego produktu. Tak czy inaczej, użyłem dwóch datepickerów współpracujących ze sobą za pomocą jquery i dyrektyw kątowych, więc pomyślałem, że podzielę się tym, aby pomóc każdemu, kto próbuje to zrobić.

Oto plunker do niego:

http://plnkr.co/edit/veEmtCM3ZnQAhGTn5EGy?p=preview

Zasadniczo inicjuje formularz za pomocą JSON. Datepickers mają swoje własne warunki, takie jak mindate itp.Pierwsze pole wyboru, jeśli true = wyłącza niedziel w kalendarzach, w przeciwnym razie je włącza.

aktualizacje ViewModel dostać, kiedy „Gotowe” kliknięciu. Oto kawałek kodu dla jednego z datepickers:

HTML:

<input id="StartDate" data-ng-model="viewModel.startdate" date-from /> 

dyrektywa:

app.directive('dateFrom', function() { 
    return function (scope, element, attrs) { 
     var doDate = $('#EndDate'); 
     element.datepicker({ 
      dateFormat: 'dd-M-yy', showOtherMonths: true, 
      selectOtherMonths: true, minDate: '0', 
      beforeShowDay: function (date) { 
       var day = date.getDay(); 
       console.log(scope.nosunday); 
       if (scope.nosunday === 'true') return [(day !== 0), '']; // disable sundays 
       else return [true, '']; 
      }, 
      onSelect: function (selectedDate) { 
       var toDate = new Date(element.datepicker("getDate")); 
       toDate.setDate(toDate.getDate() + 1); 
       doDate.datepicker('option', 'minDate', toDate); 
       scope.viewModel.startdate = selectedDate; 
       scope.viewModel.enddate = doDate.val(); 
      } 
     }); 
    } 
}) 

Zapraszam do zoptymalizować go dalej. Zamieść komentarz o rozszczepionym rzucać jeśli nie :)

6

Dla tych Googling ten problem (jak ja), prostszy sposób związania w datepicker jQuery UI z kątowym jest to zrobić ...

$.datepicker.setDefaults({ 
    // When a date is selected from the picker 
    onSelect: function(newValue) { 
     if (window.angular && angular.element) 
      // Update the angular model 
      angular.element(this).controller("ngModel").$setViewValue(newValue); 
    } 
}); 

Wystarczy umieścić go przed do kodu .datepicker() inicjalizacji.

(wzięte z innej odpowiedzi napisałem tutaj: https://stackoverflow.com/a/17206242/195835)

1

http://jsfiddle.net/9BRNf/74/ tutaj jest rozwiązanie :)

Kod:

 var myApp = angular.module('myApp', ['myApp.directives']); 


    function MainCtrl() { 

    } 

    angular.module('myApp.directives', []) 
     .directive('myDatepicker', function() { 
      return { 
      require: '?ngModel', 
       link: function (scope, element, attrs, ngModelCtrl) { 
      element.datepicker({ 
      changeYear : true, 
      changeMonth : true, 
      appendText : '(yyyy-mm-dd)', 
      dateFormat : 'yy-mm-dd', 
       onSelect: function(date) { 
        ngModelCtrl.$setViewValue(date); 
          scope.$apply(); 
       } 
      }); 
     } 
     } 

    });