【问题标题】:Live, realtime 3 ways data-binding date-time input on AngularFireAngularFire 上实时、实时的 3 种方式数据绑定日期时间输入
【发布时间】:2016-06-15 23:46:12
【问题描述】:

我的代码有以下简化版本:

tr(ng-repeat='entry in ds3.entries | orderBy:orderByField:reverseSort | filter:query as results')        
    td
      input.screen(type='datetime-local', ng-model='entry.date_received', datetime="MM/dd/yyyy hh:mm a" )
      span(ng-hide='') {{entry.date_received | dateFormat }}
tr.screen
    td
      input.screen(type='datetime-local', ng-model='new_entry.date_received', datetime="MM/dd/yyyy hh:mm a", date-parser="MM/dd/yyyy hh:mm a")
    td
      button.btn-xs.btn-success(ng-click='insert()')
        span.fa.fa-plus-square
        |   Insert

这是 HTML 视图的 Jade 部分,据称允许添加新的本地日期时间数据并更新它(如 GoogleDocs Excel 表)。

我正在尝试使用 AngularFire(AngularJS 1.x 和 Firebase 数据库)连接。我已经能够进行身份验证,并且可以为文本输入字段工作。问题是我们知道 Firebase 不接受 DATETIME 值。因此,我正在尝试为集合使用三向数据绑定,为实时、实时更改和编辑日期时间输入找出替代方案和解决方案。

我的计划是将日期时间作为整数字符串(unix_timestamp)发送到Firebase,并以日期时间格式。所以,我尝试了 2 个指令。

1- 过滤视图的整数字符串的显示结果。

angular.module('workspaceApp')
.filter('dateFormat', ['$moment', function($moment) {
    return function(time) {
      return time ? $moment.unix(time).format('MM/DD/YYYY - hh:mm a') : time;
    };
}])

2-(艰难的一个)- 将整数字符串转换并保存到 Firebase 数据库,而不会在视图上显示错误(因为事物以 3 向数据绑定 [概念] 捆绑在一起,所以我陷入困境并努力弄清楚如何正确地做到这一点)。对于文本字段,我只会在输入标签中执行 ng-change='ds3.entries.$save(entry)' 。

.directive("input", function () {
return {
    require: 'ngModel',
    /* scope : {
                   entries : "="
    },*/
    link: function (scope, elem, attr, modelCtrl) {
      if (attr['type'] === 'date' || attr['type'] === 'datetime-local') {
        modelCtrl.$formatters.push(function (modelValue) {
          if (modelValue) {
              return new Date(modelValue * 1000);
          } else {
              return null;
          }
        });
        elem.bind('change', function () {
          scope.$apply(function() {
            var str = elem.val();
            var time = new Date(elem.val());
            var unix_time = Math.floor(time.getTime() / 1000);
            console.log(str, unix_time);
            scope.entries.$save().then(function(ref) {
              ref.key() === scope.entry.$id; // true
            }, function(error) {
              console.log("Error:", error);
            });
            modelCtrl.$setViewValue(unix_time.toString());
            modelCtrl.$render();
            // $scope.entry.update(unix_time.toString());
          });
        });
      }
    }
};

})

.directive('fetchDate', function(){
return {
  link: function($scope){
    $scope.$watch('date_received', function(newVal, oldVal){
      if (newVal){
        $scope.entry.date_received = Math.floor(newVal / 1000);
        console.log($scope.entry.date_received);
      }
    });
  }
};

})

我在 datetime 输入中使用 ng-change=UpdateFunction() 并去指令和控制器编写函数但尚未解决它。我也试过 $watch 但通常会在控制台中看到未定义的旧日期或新日期。

$scope.$watch('entry.date_received',function(newVal, oldVal){
  console.log(Math.floor(newVal / 1000) , Math.floor(oldVal / 1000));
  // $scope.update(newVal);
});

但很难解决。有什么想法吗?

【问题讨论】:

  • 对于 2),我想我只是想了解一下如何在短时间内打破两种方式绑定以更新|$保存对 Firebase 的更改并且不要反馈,仅在 $formatter 到位后反馈。 ngModel.$formatters 与 ngModel.$setViewValue(unix_time.toString()); ngModel$render();
  • 这可能会有所帮助:alexperry.io/angularjs/2014/12/10/…

标签: javascript angularjs angularjs-directive firebase angularfire


【解决方案1】:

把它放在你的<input type="date" date-conversion/> 上将处理 AngularFire 和日期的 3 路绑定。

app.directive('dateConversion', function () {
return {
    restrict: "A",
    require: "ngModel",
    link(scope, element, attributes, ngModel) {
        ngModel.$formatters.push(value => {
            let output = null;
            if (value) {
                scope.stringValue = value;
            }
            if (value) { output = moment(value).toDate(); }
            return output;
        });

        ngModel.$parsers.push(value => {
            let output = null;
            if (value) { output = moment(value).format(); }
            return output;
        });
    },
}

});

【讨论】:

  • 我尝试了多种方法,这是最接近的。我确实需要将 "moment(value).format()" 更改为 ""moment(value).toDate()"" 以使其在加载和保存更改的数据时完全正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2018-10-09
  • 2017-07-12
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
相关资源
最近更新 更多