2015-11-10 18 views
6

Tôi đang sử dụng góc UI Bootstrap datepicker: https://angular-ui.github.io/bootstrap/#/datepickerParse ngày chuỗi đối tượng Date khi tải kiễu góc UI Bootstrap datepicker

Khi tôi làm cho hình thức sử dụng dữ liệu nhận được từ máy chủ, có vấn đề với các lĩnh vực datetime. datepicker đầu vào của tôi trông như thế này:

<form name="itemForm"> 
    <input type="datetime" class="form-control" id="startedAt" name="startedAt" 
      ng-model="item.startedAt" 
      ng-click="open($event, 'startedAt')" 
      uib-datepicker-popup="yyyy-MM-dd" 
      is-open="datepickers.startedAt" 
    /> 
</form> 

My server trả về datetime phản ứng như JSON chuỗi:

{  
    ... 
    startedAt: "2015-05-29T02:00:00+0200" 
} 

Khi tôi gán dữ liệu đáp ứng với mô hình $scope.item = response;, datepicker trường nhập được trả lại một cách chính xác (đúng ngày là được chọn và được định dạng đúng theo định dạng mà tôi đã chọn). Vấn đề là việc xác nhận không vượt qua. Tôi nhận được:

itemForm.startedAt.$invalid == true 

tôi nhận thấy rằng dữ liệu ràng buộc với lĩnh vực datepicker nên Date đối tượng và không dây (khi tôi chọn ngày mới từ datepicker, $scope.item.startedAt là một Date)

tôi quản lý để làm việc xung quanh vấn đề này và làm điều này trong bộ điều khiển:

$scope.item = response; 
$scope.item.startedAt = new Date($scope.item.startedAt); 

Nó hoạt động theo cách này ... Nhưng tôi không muốn chuyển đổi thủ công chuỗi ngày mỗi khi tôi nhận được phản hồi từ máy chủ. Tôi cố gắng để tạo ra một chỉ thị, mà tôi có thể gán cho lĩnh vực datepicker đầu vào để nó chuyển đổi ng-model cho tôi:

.directive("asDate", function() { 
    return { 
     require: 'ngModel', 
     link: function (scope, element, attrs, modelCtrl) { 

      modelCtrl.$formatters.push(function (input) { 

       var transformedInput = new Date(input); 

       if (transformedInput != input) { 
        modelCtrl.$setViewValue(transformedInput); 
        modelCtrl.$render(); 
       } 

       return transformedInput; 
      }); 
     } 
    } 
}) 

Vâng nó hoạt động, bởi vì bây giờ tôi có thể nhìn thấy Date đối tượng, khi tôi ra mô hình theo quan điểm của tôi : {{item.startedAt}}. Tuy nhiên vẫn còn xác thực không thành công! Tôi nghi ngờ đây là một số vấn đề với tôi hiểu làm thế nào dữ liệu chảy giữa mô hình và xem, và làm thế nào giao diện người dùng Bootstrap móc vào nó.

Ngoài ra khi tôi thay đổi chỉ thị của tôi $formatters.push-$formatters.unshift, xác nhận hoạt động OK, nhưng datepicker không định dạng datetime của tôi (insted của độc đáo formattet yyyy-MM-dd tôi thấy ISO chuỗi bên trong đầu vào)

+1

Aww người đàn ông này, chúng tôi đang gặp vấn đề chính xác cùng here !!! –

+0

@VictorParmar hiện tôi đang làm điều này theo cách - chuyển đổi chuỗi phản ứng thành đối tượng Ngày khi nhận từ máy chủ. Và chuyển đổi đối tượng Date thành chuỗi khi gửi đến máy chủ. Tất cả điều này được thực hiện trong bộ điều khiển góc bằng tay. Có lẽ tôi sẽ trích xuất logic này như dịch vụ Góc, nhưng tôi không nghĩ rằng nó có thể làm với chỉ thị – rsobon

+2

yeah tham gia câu lạc bộ - chúng tôi đã làm điều tương tự :) –

Trả lời

1

Vì đây là cố ý hành vi của angular-ui-bootstrap datepicker (https://github.com/angular-ui/bootstrap/issues/4690), tôi đã kết thúc bằng cách sử dụng dịch vụ/nhà máy Angular và thư viện moment.

Dịch vụ dateConverter có thể được tiêm trên toàn cầu để chặn tất cả các yêu cầu/phản hồi HTTP hoặc chỉ trong các bộ điều khiển mong muốn.

Ở đây tôi sử dụng thư viện Restangular để xử lý yêu cầu REST API, do đó phương thức response.plain() chỉ lấy thuộc tính đối tượng chứ không phải phương thức/thuộc tính Restangular.

var Services = angular.module('app.Services', []); 

Services 
    .factory('dateConverter', ['dateFilter', function (dateFilter) { 

     var dateConverter = {}; 

     dateConverter.prepareResponse = function (response) { 
      for(prop in response.plain()) { 
       if (response.hasOwnProperty(prop)) { 
        if(moment(response[prop], moment.ISO_8601, true).isValid()) { 
         response[prop] = new Date(response[prop]); 
        } 
       } 
      } 
      return response; 
     }; 

     dateConverter.prepareRequest = function (item) { 
      for(prop in item.plain()) { 
       if (item.hasOwnProperty(prop)) { 
        if(angular.isDate(item[prop])){ 
         item[prop] = dateFilter(item[prop] , "yyyy-MM-ddTHH:mm:ssZ") 
        } 
       } 
      } 
      return item; 
     }; 

     return dateConverter; 
    }]) 
; 
0

này đã phá vỡ như các góc. UI.Bootstrap v0.13.2 (8-2-2015) Hạ cấp xuống còn 0,13,1 công trình, đó là nơi tôi bị kẹt hôm nay.

Wesleycho nói rằng điều này đã được thực hiện cố ý https://github.com/angular-ui/bootstrap/issues/4690

tôi đã sẵn sàng cho ngày hái khác có hỗ trợ dây nếu có ai có một gợi ý

... ngay sau khi gửi bài này tôi đã đi xuống một tổ chức phi góc con đường mà tôi không tự hào, nhưng nó hoạt động cho cả HTML5 type = "date" và uib-datepicker-popup. Tôi có một biểu thức chính quy xác định xem một chuỗi có giống như một trong hai định dạng ngày được tuần tự hóa mà tôi đã thấy hay không và sau đó tôi có hàm javascript đệ quy để đi qua cây json và thay thế các chuỗi đó bằng Date(). Bạn sẽ gọi nó ngay trước khi bạn đặt trong phạm vi $ (hoặc viewmodel) ...

$http.get("../api/comm/" + commId 
    ).success(function (resp) { 
     fixDates(resp); 
     vm.comm = resp; 
    }); 

(Tôi không cần phải kiểm tra độ dài chuỗi, nhưng tôi figured nó sẽ tha cho một số chu kỳ CPU bằng cách không chạy regex nếu chuỗi là rõ ràng không phải là một ngày)

//2015-10-01T00:00:00-04:00 
//2015-11-20T18:15:56.6229516-05:00 
var isDate = new RegExp("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{7})?-\\d{2}:00"); 

function fixDates(json) { 
    for (i in json) 
     if (typeof (json[i]) == "object") 
      fixDates(json[i]); 
     else if (typeof (json[i]) == "string" && (json[i].length == 25 || json[i].length == 33) && isDate.test(json[i])) 
      json[i] = new Date(json[i]); 
}; 
+0

khi bạn đang sử dụng javascript for-in loop bạn có thể xảy ra cũng nên sử dụng hasOwnProperty() – rsobon

0

bạn có thể chuyển đổi String để ngày trong biến restangular, một cái gì đó giống như

RestangularConfigurer 
    .addElementTransformer('<RESTRESOURCENAME>', false, function (element) { 
     element.createDate = new Date(element.createDate); 
     return element; 
    }) 
Các vấn đề liên quan