web-dev-qa-db-ja.com

ng-model文字列をangular material datepickerの日付にフォーマットする方法

コレクションにDateオブジェクトを含むデータベースへのmongoose接続があります。 Angular MaterialのDatePickerコントロールを使用してこれらのDateオブジェクトを表示します。DateオブジェクトはISO文字列形式に従います。

コードスニペットは次のとおりです。

<md-datepicker 
     ng-model="license.expirationdate" md-placeholder="Enter date">
</md-datepicker>    

次のエラーが表示されます。

ng-modelmd-datepickerは、Dateインスタンスでなければなりません。

調査中に、フィルターを使用してDateインスタンスを作成できることがわかりましたが、これはうまくいきませんでした->単純なフィルターを使用するとモデル値は割り当てられないというエラーメッセージが表示されました。フィルターは、文字列入力に基づいて新しいDateオブジェクトを返しました。

ng-modelの変更を許可しながら、文字列をDateオブジェクトにフォーマットするにはどうすればよいですか?

編集:mongooseのスキーマvar Schema = mongoose.Schema;

var Schema = mongoose.Schema;

var modelschema = new Schema({
    name : String,
    licensetype : String,
    activationcount : Number,
    expirationdate: Date,
    key : String
})

ここに、スキーマに入力する高速ルーティングがあります

app.post('/licenses', function (req, res) {

    console.log(req.body.expirationDate);
    License.create({

        name: req.body.licenseName,
        licensetype: req.body.licenseType,
        activationcount: 0,
        expirationdate: req.body.expirationDate,
        key: "123456"
    }, function (err, license) {

        if (err) {
            res.send(err);
            console.log(err);
        }

        //Send user back to main page
        res.writeHead(301, {
            'Location': '/',
            'Content-Type': 'text/plain'
        });
        res.end();
    }
    )

});
15
WJM

以下に例を示します。

マークアップ:

<div ng-controller="MyCtrl">
    <md-datepicker ng-model="dt" md-placeholder="Enter date" ng-change="license.expirationdate = dt.toISOString()">
    </md-datepicker>
    {{license.expirationdate}}
</div>

JavaScript:

app.controller('MyCtrl', function($scope) {

    $scope.license = {
        expirationdate: '2015-12-15T23:00:00.000Z'
    };

    $scope.dt = new Date($scope.license.expirationdate);

});

フィドル: http://jsfiddle.net/masa671/jm6y12un/

更新:

ng-repeat

マークアップ:

<div ng-controller="MyCtrl">
    <div ng-repeat="d in data">
        <md-datepicker
            ng-model="dataMod[$index].dt"
            md-placeholder="Enter date"
            ng-change="d.license.expirationdate = dataMod[$index].dt.toISOString()">
        </md-datepicker>
        {{d.license.expirationdate}}
    </div>
</div>

JavaScript:

app.controller('MyCtrl', function($scope) {
    var i;

    $scope.data = [ 
        { license:
            { expirationdate: '2015-12-15T23:00:00.000Z' }
        },
        { license:
            { expirationdate: '2015-12-20T23:00:00.000Z' }
        },
        { license:
            { expirationdate: '2015-12-25T23:00:00.000Z' }
        }
    ];

    $scope.dataMod = [];
    for (i = 0; i < $scope.data.length; i += 1) {
        $scope.dataMod.Push({
            dt: new Date($scope.data[i].license.expirationdate)
        });
    }
});

フィドル: http://jsfiddle.net/masa671/bmqpyu8g/

16
masa

Ng-init、カスタムフィルター、およびng-changeを使用して、マークアップでこれを実行できます。

JavaScript:

app.filter('toDate', function() {
    return function(input) {
        return new Date(input);
    }
})

HTML:

<md-datepicker
     ng-init="date = (license.expirationdate | toDate)"
     ng-model="date"
     ng-change="license.expirationdate = date.toISOString()"
     md-placeholder="Enter date">
</md-datepicker>

このアプローチでは、Viewロジックでコントローラーコードを乱雑にする必要はありません。欠点は、Controllerのlicense.expirationdateに対するプログラムによる変更がViewに自動的に反映されないことです。

10

http://jsfiddle.net/katfby9L/1/

// Configure the $httpProvider by adding our date transformer
app.config(["$httpProvider", function ($httpProvider) {
    $httpProvider.defaults.transformResponse.Push(function(responseData){
        convertDateStringsToDates(responseData);
        return responseData;
    });
}]);

var regexIso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;

function convertDateStringsToDates(input) {
    // Ignore things that aren't objects.
    if (typeof input !== "object") return input;

    for (var key in input) {
        if (!input.hasOwnProperty(key)) continue;

        var value = input[key];
        var match;
        // Check for string properties which look like dates.
        // TODO: Improve this regex to better match ISO 8601 date strings.
        if (typeof value === "string" && (match = value.match(regexIso8601))) {
            // Assume that Date.parse can parse ISO 8601 strings, or has been shimmed in older browsers to do so.
            var milliseconds = Date.parse(match[0]);
            if (!isNaN(milliseconds)) {
                input[key] = new Date(milliseconds);
            }
        } else if (typeof value === "object") {
            // Recurse into object
            convertDateStringsToDates(value);
        }
    }
}

これにより、サーバーのJSON応答のすべての文字列が自動的に最新に変換されます

8
Toolkit

私はこのようにします:

HTML:

<div ng-controller="MyCtrl">
    <div ng-repeat="d in data">
        <md-datepicker
            ng-init="date = StrToDate(d.license.expirationdate);"
            ng-model="date"
            md-placeholder="Enter date"
            ng-change="d.license.expirationdate = date.toISOString()">
        </md-datepicker>
        {{d.license.expirationdate}}
    </div>
</div>

コントローラーで

$scope.StrToDate = function (str) {
            return new Date(str);
        }
7
mudin

現在の日付から6か月のデフォルトの日付を作成する必要がありました...

ISO形式への日付変換とその逆の非常に長い実験の後、私はここで見つけられなかった簡単なソリューションを作成しました。

一般的なアイデア:今日時間を取り、必要な日付までミリ秒単位で時間を加算/減算します。

html:

<div flex-gt-xs>
   <h4 class="md-title">Date From:</h4>
      <md-datepicker ng-model="vm.sixMonthBeforeNow" md-placeholder="Date From:"></md-datepicker>
      {{vm.sixMonthBeforeNow}}
</div>

コントローラ:

vm.sixMonthBeforeNow = new Date((+new Date) - 15778800000); // today - 6 month in ISO format (native for Angular Material Datepicker)

結果: enter image description here

たぶんそれは誰かに役立つでしょう...

1
Igor Arkhipenko

これを処理するカスタムディレクティブを作成しました。 Sugarjs.com のDateクラスを使用して、実装したとおりに機能するようにしました。この方法により、日付は常に日付のように表示され、UTCオフセットが関係してジャンプすることはありません。 UTCに限定したくない場合は、フォーマッターをreturn new Date(input)に変更できます。

angular.module 'app.components'
 .directive 'autoChangeStringDates', ->
   directive =
     restrict: 'A'
     require: 'ngModel'
     priority: 2000
     link: (scope, el, attrs, ngModelController) ->
       ngModelController.$formatters.Push((input) ->
         if typeof input == Date
          return input
         else
           return Date.create(input, {fromUTC: true})
       )
    return

その後、HTMLマークアップで次のように使用します

<md-datepicker ng-model='myModel' auto-change-string-dates></md-datepicker>
0
Tyrone Wilson