检查 angularjs 中未保存的表单数据(使用 ui-router 的多个表单)

Posted

技术标签:

【中文标题】检查 angularjs 中未保存的表单数据(使用 ui-router 的多个表单)【英文标题】:check for unsaved form data in angularjs ( multiple forms using ui-router ) 【发布时间】:2016-07-16 06:34:44 【问题描述】:

实现细节:

我正在使用 ui-router 在 ui-view div 中加载表单页面。我通过Andres Ekdahi 引用了一个很好的例子,我如何使用相同的指令对多个表单进行 $dirty 检查?

表格1

 <form name="myForm" ng-controller="Controller" confirm-on-exit>

表格2

<form name="iForm" ng-controller="Controller" confirm-on-exit ng-model="myModel">

app.js(指令)

myApp.directive('confirmOnExit', function() 
        return 
            link: function($scope, elem, attrs) 
                // condition when back page is pressed 
                window.onbeforeunload = function()
                    if ($scope.myForm.$dirty) 
                        return "The formI is dirty, do you want to stay on the page?";
                    
                
                // condition when user try to load other form (via icons )
                $scope.$on('$stateChangeStart', function(event, next, current) 
                    if ($scope.myForm.$dirty) 
                        if(!confirm("myForm. Do you want to continue ?")) 
                            event.preventDefault();
                        
                    

                    if ($scope.iForm.$dirty) 
                        if(!confirm("iform. Do you want to continue ?")) 
                            event.preventDefault();
                        
                    
                );
            
        ;
    );

错误:

第一次加载页面时,$dirty 值为 false。然后我填写表单详细信息并单击第三个图标(文件),第二个表单脏检查if ($scope.iForm.$dirty) 和警报中的$dirty 出现错误。

angular.js:12520 TypeError: Cannot read property '$dirty' of undefined

<form name="iForm" ng-controller="Controller" confirm-on-exit="" ng-model="myModel" class="ng-pristine ng-untouched ng-valid ng-scope">

演示:Plunker

【问题讨论】:

【参考方案1】:

有一个更简单的方法。

只需将您的指令放在表单元素上并通过链接功能访问表单控制器:

myApp.directive('confirmOnExit', function() 
        return 
            require: 'form',
            link: function($scope, elem, attrs, formController) 
                // condition when back page is pressed 
                window.onbeforeunload = function()
                    if (formController.$dirty) 
                        return "The form '" + formController.$name + "' is dirty, do you want to stay on the page?";
                    
                
                // condition when user try to load other form (via icons )
                $scope.$on('$stateChangeStart', function(event, next, current) 
                    if (formController.$dirty) 
                        if(!confirm(formController.$name + ". Do you want to continue ?")) 
                            event.preventDefault();
                        
                    
                );
            
        ;
    );

【讨论】:

【参考方案2】:

通过从formname 属性中获取指令,使指令更简单,因此指令中只有一个条件,并且可以在许多地方重复使用。

<form name="myForm" ng-controller="Controller" confirm-on-exit>

代码

var form = $scope[attrs.name]; //which will take out form name & do search that inside scope
if (form.$dirty)  //form object would always exist, to make sure you could also add one more check `form &&`
    if(!confirm("myForm. Do you want to continue ?")) 
        event.preventDefault();
    

Demo here

【讨论】:

你能解释一下$scope[attrs.name] 寻找什么吗?这是否仅适用于表单数据更改或任何用户点击? @Mad-D 将取出表单名称,并将在控制器范围内搜索 formName 谢谢先生,我想这正是我需要做的。 别叫我先生,我和你一样。很高兴能帮助你。谢谢;)【参考方案3】:

在检查表单是否脏之前检查表单是否存在。做类似的事情

if ($scope.myForm && $scope.myForm.$dirty) 
    if(!confirm("myForm. Do you want to continue ?")) 
        event.preventDefault();
    


if ($scope.iForm && $scope.iForm.$dirty) 
    if(!confirm("iform. Do you want to continue ?")) 
        event.preventDefault();
    

【讨论】:

谢谢,你的回答也是对的。我只需要检查表单是否存在。

以上是关于检查 angularjs 中未保存的表单数据(使用 ui-router 的多个表单)的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS模态对话框表单对象在控制器中未定义

使用 Web API 和 AngularJS 保存表单数据(选择列表)

在 SessionStorage 中未保存更改时警告用户

如何使用jquery检查表单中未选中的radio,定位到这个radio并输出提示信息

jQuery 中未检测到简单表单 ID

使用 Angularjs 和 Nodejs 从 HTML 表单另存为 JSON 文件