angularjs 自动保存表单是正确的方法吗?

标签 angularjs angularjs-directive restangular

我的目标是在有效后自动保存表单并在超时时更新它。
我设置如下:

(function(window, angular, undefined) {
    'use strict';
    angular.module('nodblog.api.article', ['restangular'])
        .config(function (RestangularProvider) {
            RestangularProvider.setBaseUrl('/api');
            RestangularProvider.setRestangularFields({
                id: "_id"
            });
            RestangularProvider.setRequestInterceptor(function(elem, operation, what) {
                if (operation === 'put') {
                    elem._id = undefined;
                    return elem;
                }
                return elem;
            }); 
        })
        .provider('Article', function() {
            this.$get = function(Restangular) {
                function ngArticle() {};
                ngArticle.prototype.articles = Restangular.all('articles');
                ngArticle.prototype.one = function(id) {
                    return Restangular.one('articles', id).get();
                };
                ngArticle.prototype.all = function() {
                    return this.articles.getList();
                };
                ngArticle.prototype.store = function(data) {
                    return this.articles.post(data);
                };
                ngArticle.prototype.copy = function(original) {
                    return  Restangular.copy(original);
                };
                return new ngArticle;
            }
    })
})(window, angular);

angular.module('nodblog',['nodblog.route'])
.directive("autosaveForm", function($timeout,Article) {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {
            var id = null;
            scope.$watch('form.$valid', function(validity) {
                if(validity){
                    Article.store(scope.article).then(
                        function(data) {
                            scope.article = Article.copy(data);
                            _autosave();
                        }, 
                        function error(reason) {
                            throw new Error(reason);
                        }
                    );
                }  
            })
            function _autosave(){
                    scope.article.put().then(
                    function() {
                        $timeout(_autosave, 5000); 
                    },
                    function error(reason) {
                        throw new Error(reason);
                    }
                );
            }
        }
    }
})

.controller('CreateCtrl', function ($scope,$location,Article) {
        $scope.article = {};
        $scope.save = function(){
            if(typeof $scope.article.put === 'function'){
                $scope.article.put().then(function() {
                    return $location.path('/blog');
                });
            }
            else{
                Article.store($scope.article).then(
                    function(data) {
                        return $location.path('/blog');
                    }, 
                    function error(reason) {
                        throw new Error(reason);
                    }
                );
            }
        };
     })

我想知道是否有最好的方法。

最佳答案

查看我可以看到的代码,如果当前输入有效并且用户更改了任何有效的内容,则 $watch 将不会重新触发。这是因为只有在值发生变化时才会执行监视功能。
您还应该检查表单的脏状态并在表单数据被持久化后重置它,否则你会得到一个无休止的持久循环。

并且您没有清除任何以前的超时。

如果当前超时正在进行,当前代码将保存无效数据。

我已经制定了一个指令来完成这一切并且有更好的 SOC所以它可以重复使用。只需为它提供一个回调表达式就可以了。

See it in action in this plunker.

演示 Controller

myApp.controller('MyController', function($scope) {

  $scope.form = {
    state: {},
    data: {}
  };

  $scope.saveForm = function() {
    console.log('Saving form data ...', $scope.form.data);  
  };

});

演示 Html
  <div ng-controller="MyController">

    <form name="form.state" auto-save-form="saveForm()">

      <div>
        <label>Numbers only</label>
        <input name="text" 
               ng-model="form.data.text" 
               ng-pattern="/^\d+$/"/>
      </div>

      <span ng-if="form.state.$dirty && form.state.$valid">Updating ...</span>      

    </form>
  </div>

指令
myApp.directive('autoSaveForm', function($timeout) {

  return {
    require: ['^form'],
    link: function($scope, $element, $attrs, $ctrls) {

      var $formCtrl = $ctrls[0];
      var savePromise = null;
      var expression = $attrs.autoSaveForm || 'true';

      $scope.$watch(function() {

        if($formCtrl.$valid && $formCtrl.$dirty) {

          if(savePromise) {
            $timeout.cancel(savePromise);
          }

          savePromise = $timeout(function() {

            savePromise = null;

            // Still valid?

            if($formCtrl.$valid) {

              if($scope.$eval(expression) !== false) {
                console.log('Form data persisted -- setting prestine flag');
                $formCtrl.$setPristine();  
              }

            }

          }, 500);
        }

      });
    }
  };

});

关于angularjs 自动保存表单是正确的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21135302/

相关文章:

angularjs - 嵌套指令未编译

javascript - Angular JS 和 Restangular : How to include a header and parameters in POST request?

带有 ngx-restangular 的 Angular 4 拦截器

javascript - 具有隔离范围的指令内的 Angular 形式

javascript - 在 AngularJS 中使用延迟结果

angularjs - 带有 RequireJs 的 Angular-Material

javascript - 如何将一个数组映射到另一个具有不同值的数组(angularJs)

javascript - AngularJS组织简单的Ajax程序?

php - 如何将我的 angularjs 变量传递给 Php 页面并检索它

javascript - AngularJS:在链接方法中添加指令的范围