Live, realtime 3 ways data-binding date-time input on AngularFire

守給你的承諾、 提交于 2019-12-13 07:15:12

问题


I have the following simplified version of my code:

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

That is the Jade part for HTML view, allowing supposedly adding new datetime-local data and updating it live (like an GoogleDocs Excel table).

I'm trying to wire things up using AngularFire (AngularJS 1.x and Firebase database). I had been able to have Auth and things worked for text input field. Problem is as we know Firebase doesn't accept DATETIME value. So, I'm trying to sort out alternatives and workaround solutions for live, realtime changing and editing of datetime input using 3-ways data binding for a collection.

My planning is to have datetime sent to Firebase as integer string (unix_timestamp) and feed back as a datetime format. So, I try 2 directives.

1- to filter display result from integer string for the view.

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-(tough one)- to convert and save integer string to Firebase database without showing error on the view (because things tied together in 3-ways data binding [concept] so I'm stucked and struggling at figuring out how to do it properly). For text field, I would only do ng-change='ds3.entries.$save(entry)' in the input tag.

.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);
      }
    });
  }
};

})

I went with ng-change=UpdateFunction() in the datetime input and went to directive and controller to write the function but not yet solve it. I tried $watch too but usually see undefined either old date or new date in the console.

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

But hardly get it solved. Any ideas?


回答1:


Putting this on your <input type="date" date-conversion/> will handle 3 way binding with AngularFire and dates.

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;
        });
    },
}

});



来源:https://stackoverflow.com/questions/37847600/live-realtime-3-ways-data-binding-date-time-input-on-angularfire

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