2012-05-23 6 views
8

Actualmente estoy transfiriendo una gran aplicación a una aplicación web basada en HTML5 - comencé a construir la aplicación en AngularJS y disfrutando del poder del framework AngularJS - tengo un problema en mi camino Actualmente:AngularJS - jQuery UI - problema de vinculación

Tengo una directiva que me da un jQuery Datepicker pero parece que el enlace al modelo no funciona.

http://jsfiddle.net/9BRNf/

Probablemente soy la mala interpretación del camino directivas trabajan y les gustaría ver si puedo arreglar esta parte de mi comprensión del marco. He analizado un montón de ejemplos (incluido el proyecto angularui en github pero todavía no tiene sentido de por qué no está sucediendo el enlace)

cualquier ayuda será muy apreciada.

+1

bien, así me parece que tiene una solución - http : //jsfiddle.net/9BRNf/2/ - aún me gustaría saber si esta es la forma correcta/mejor de tratar este problema. –

+0

Creo que onSelect of datepicker no es necesario. Los valores ya estarán vinculados al modelo cuando se cambie el seleccionador. – dj2

+0

@ dj2 eso es lo que pensé, pero revisa el violín en el mensaje original: el modelo no es vinculante. –

Respuesta

4

En primer lugar, es genial que estés usando angularjs, es un marco dulce. Un proyecto derivado se inició hace un tiempo atrás para tratar cosas como envolver jquery-ui y crear módulos de interfaz de usuario.

A continuación se muestra el enlace a la implementación de Peter Bacon Darwin.

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

--Dan

+0

Gracias Dan - lo que es extraño es que en realidad probé AngularUI hace un día y me dio exactamente el mismo problema vinculante. Sin embargo, lo he intentado de nuevo ahora http://jsfiddle.net/9BRNf/6/ y funciona perfectamente. –

+0

Esto todavía no funciona con la última versión de AngularJS (1.0.2 & Angular-UI (tomó el último día de hoy) :-( –

+0

Sutikshan, ¿puedes publicar un violín/plunkr describiendo lo que no funciona? Y dar más información, como los navegadores utilizados. El ejemplo de Dinesh está funcionando bien. Sí sé que hay algunos problemas que se informan pero funciona. –

2

El selector de fechas angular-ui no funcionaba con angular 1.0.0, por lo que se volvió a escribir. Mi tenedor le da la capacidad de establecer cómo se formatea la fecha dentro de la entrada y cómo se guarda de nuevo en el modelo. Código

: https://gist.github.com/2967979 jsFiddle: http://jsfiddle.net/m8L8Y/8/ (Le faltan estilos jquery-ui, pero funciona de la misma manera)


// 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

Publique su código en su respuesta, ya que su respuesta es útil si Gist o JSFiddle no están disponibles por algún motivo. –

0

Acababa recortado el código, echar un vistazo a esto: 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

Publique su código en su respuesta, ya que su respuesta aún es útil si JSFiddle no está disponible por algún motivo. –

2

similares a praveepd (usando sus años como base), pero esto incluirá la selección del modelo de profundidad.

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

Para mejorar la calidad de su publicación, por favor incluya cómo y por qué su publicación resolverá el problema –

0

pregunta antiguo, pero esto fue el primer éxito para mí en la búsqueda de google para esto. De todas formas, utilicé los datapickers duales trabajando juntos usando jquery y directivas angulares, así que pensé en compartir para ayudar a cualquier otra persona que intentara hacer esto.

Aquí está la plunker para ello:

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

Básicamente se inicializa el formulario utilizando JSON. Los datapickers tienen sus propias condiciones, como mindate's, etc.El primer cuadro de selección si es verdadero = deshabilita los domingos en los calendarios, de lo contrario los habilita.

El viewmodel obtiene las actualizaciones cuando se hace clic en 'hecho'. Aquí hay un poco de código para uno de los datepickers:

HTML:

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

Directiva:

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

dude para optimizar aún más. Publicar un comentario con un golpe seco en forma de horquilla si lo hace :)

6

Para aquellos googlear este tema (como yo), una forma más simple de atar en el selector de fechas con jQuery UI angular es hacer esto ...

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

Simplemente colóquelo anterior a su código de inicialización .datepicker().

(Tomado de otra respuesta que he publicado aquí: https://stackoverflow.com/a/17206242/195835)

1

http://jsfiddle.net/9BRNf/74/ Aquí está la solución :)

código:

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

    });