binding a date in angularjs using webapi and the bootstrap date picker

半城伤御伤魂 提交于 2020-01-24 03:53:26

问题


Given a WebApi2 service that returns json values like this:

{
    id: 1109,
    effectiveDate: "2014-10-05T00:00:00", // the date is a string (newtonsoft.json)
    text: "Duis et rhoncus nibh. Cras rhoncus cursus diam",
    fundSource: "Test"
}

I need the date to appear in the bound angular / bootstrap / date picker correctly.

I need to transform the date into the format yyyy-mm-dd (without the time) when binding it to an input box. Just a pointer to some documentation explaining what the correct way to serialize dates from the API to angular. I am sure that effectiveDate should actually be a Date object and not a string.

<input class="form-control" 
       type="text" 
       name="effectiveDate" 
       ng-model="consultation.effectiveDate" 
       data-date-picker="yyyy-mm-dd" 
       placeholder="Date" />

For completness, the service returning the json values looks like this:

app.factory('Service', ['$http', '$location', '$interpolate', function ($http, $location, $interpolate) {
    return {
        get: function (account) {
            var url = 'api/consultations/{account}';
            return $http
                .get(Api.format(url, { account: account }))
                .then(function (response) { return response.data; });
        }
    };
}]);

The controller method calls it like this:

service.get($scope.urlData.account).then(function(consultations) {
    $scope.consultations = consultations;
});

回答1:


If you want to use bootstrap components in angular then you have to create a directive or you can reuse some existing like http://angular-ui.github.io/bootstrap/#/datepicker

Example how to use bootstrap date picker with angular:

 <body ng-app="app" >

    <div class="form-horizontal" ng-controller="ctrl">
        <input type="text" datepicker-popup="MM/dd/yyyy" ng-model="consultation.effectiveDate" datepicker-options="dateOptions" date-disabled="" ng-required="true" />
    </div>
 </body>

js:

app.controller('ctrl', function ($scope, $timeout) {

 $scope.consultation = {
    id: 1109,
    effectiveDate: "2014-10-05T00:00:00", // the date is a string (newtonsoft.json)
    text: "Duis et rhoncus nibh. Cras rhoncus cursus diam",
    fundSource: "Test"
  };

  $scope.dateOptions = {
    'starting-day': 1
  };
});

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




回答2:


I ran into the exact same problem and eventually solved it by writing an Angular http interceptor. It parses the server's response and converts all Datetime strings with ISO/UTC format into actual JavaScript date objects. This allows direct binding to the datepicker and solves validation issues.

Here's the client-side Angular code, consisting of a factory (the interceptor) and the config part for providing the http interceptor:

angular.module("app")
    .factory('dateInterceptor', function () {
        var regexIsoUtc = /^(\d{4}|\+\d{6})(?:-(\d{2}))(?:-(\d{2}))(?:T(\d{2})):(\d{2}):(\d{2})Z$/;

        function matchDate(dateString) {
            if (dateString.length === 20) {
                return dateString.match(regexIsoUtc);
            }
            return false;
        };

        function convertDateStringsToDates(object) {
            // ensure that we're processing an object
            if (typeof object !== "object") {
                return object;
            }

            for (var key in object) {
                if (!object.hasOwnProperty(key)) {
                    continue;
                }
                var value = object[key];

                // check for string properties with a date format
                if (typeof value === "string" && matchDate(value)) {
                    var date = new Date(value); // create the date from the date string
                    object[key] = date; // we're mutating the response directly
                } else if (typeof value === "object") {
                    convertDateStringsToDates(value); // recurse into object
                }
            }
            return null;
        }

        var interceptor = {
            'response': function (response) {
                if (response.data) {
                    convertDateStringsToDates(response.data);
                }
                return response;
            }
        };
        return interceptor;
    })

    .config(["$httpProvider", function ($httpProvider) {
        $httpProvider.interceptors.push('dateInterceptor'); // intercept responses and convert date strings into real dates
    }]);

On the server side I configured Newtonsoft.Json to serialize dates using the ISO format with UTC time zone, which is the format I test against in the interceptor:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var formatters = GlobalConfiguration.Configuration.Formatters;
        var jsonFormatter = formatters.JsonFormatter;
        var settings = jsonFormatter.SerializerSettings;

        // serialize dates into ISO format with UTC timezone
        settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
        settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

The interceptor is thankfully based on the code from Automatic JSON date parsing with AngularJS and AngularJS HTTP Date Interceptor Factory.




回答3:


Use angular filter module Date filter in angularjs

{{ effectiveDate | date:'yyyy-MM-dd' }}


来源:https://stackoverflow.com/questions/26249052/binding-a-date-in-angularjs-using-webapi-and-the-bootstrap-date-picker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!