带AngularJS和Firebase的三向绑定日期格式

带AngularJS和Firebase的三向绑定日期格式,angularjs,firebase,bind,datapicker,Angularjs,Firebase,Bind,Datapicker,在我所有的项目中,我都遇到了同样的问题,试图找出最好的方法是用我的视图和Firebase绑定时间戳(日期)。我目前正在使用Angular Material的md datepicker指令,但不幸的是,该指令仅支持日期对象,而且由于Firebase不接受日期对象,因此该值始终为空 在几个项目中,我在Firebase中以毫秒为单位存储历元时间戳。在Firebase和md datepicker中是否有可能使用历元时间戳进行适当的3向数据绑定 谢谢 通过创建我自己的绑定函数并在保存时转换为ISO日期字符

在我所有的项目中,我都遇到了同样的问题,试图找出最好的方法是用我的视图和Firebase绑定时间戳(日期)。我目前正在使用Angular Material的
md datepicker
指令,但不幸的是,该指令仅支持日期对象,而且由于Firebase不接受日期对象,因此该值始终为空

在几个项目中,我在Firebase中以毫秒为单位存储历元时间戳。在Firebase和
md datepicker
中是否有可能使用历元时间戳进行适当的3向数据绑定


谢谢

通过创建我自己的绑定函数并在保存时转换为ISO日期字符串,在获取时将其转换为日期对象,解决了这个问题

它允许用户$parse计算给定范围内的表达式并更新该范围内的局部变量。服务内容如下:

angular.module('symApp').service('realtimeService', function($rootScope, $q, $log, $window, $state,
                                                           $firebaseObject, $parse) {

// Utilities
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)?)?)?)?$/;
var convertDateStringsToDates = function (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.
        if (typeof value === "string" && (match = value.match(regexIso8601))) {
            var milliseconds = Date.parse(match[0]);
            if (!isNaN(milliseconds)) {
                input[key] = new Date(milliseconds);
            }
        } else if (typeof value === "object") {
            // Recurse into object
            convertDateStringsToDates(value);
        }
    }
};

this.bindVar = function(scope, remote_path, local_var_name) {
// This function binds a local variable in scope to a remote variable in firebase
// and handles any dates by converting them into iso formatted strings.
// Note: Arrays inside the object are not supported

// Parse the local variable name so we can interact with the scope variable
var parsed = $parse(local_var_name);

// Grab the reference to the realtime database
var ref = firebase.database().ref().child(remote_path);

// Create the firebase object and set watchers to bind the data
var remote = $firebaseObject(ref);
remote.$loaded().then(function() {

    // Watch for changes and call $save on firebaseObject
    // Have to do this when loaded otherwise we'll get a change from nothing to null and write null to realtime database...

    // Local watcher
    scope.$watch(local_var_name,
        function(value) {
            // This is called when the local variable changes
            $log.debug(local_var_name, 'local value changed');

            // Convert to JSON to change dates to strings
            var local = angular.fromJson(angular.toJson(parsed(scope)));

            // Check if local has changed with respect to remote (stops us from saving when we don't need to)
            if(!angular.equals(remote.value, local)){
                remote.value = local;
                remote.$save();
                $log.debug(local_var_name, 'saved to remote with value: ', remote.value);
            }
        },
        true
    );

    // Remote watcher
    scope.$watch(
        function () {
            return remote.value;
        },
        function(value) {
            // If the firebase value has changed, then update the local value
            $log.debug(local_var_name, 'remote value changed');

            // Convert date strings from firebase into date objects before setting scope variable
            var remote_with_date_objects = $.extend(true,{},remote.value);
            convertDateStringsToDates(remote_with_date_objects);

            if(!angular.equals(remote_with_date_objects,parsed(scope))){
                parsed.assign(scope, remote_with_date_objects);
                $log.debug(local_var_name, 'updated with remote value: ', remote_with_date_objects);
            }
        },
        true
    );

    });
};
}))

下面是如何在控制器中使用它绑定范围变量:

realtimeService.bindVar($scope, 'datum/charter', 'charter');
My$scope.charter对象中有自己的对象和数组,所有内容似乎都正确同步。保存数据时,它使用angular.toJsonangular.fromJson将所有日期对象转换为字符串。加载远程数据时,它使用自定义函数convertDateStringsToDates()在更新远程数据时将对象中的任何日期字符串转换为日期对象