监视具有基于表单和非基于表单的属性的对象中的更改

Watch for changes in object with form based and non-form based properties

本文关键字:表单 于表单 对象 属性 监视      更新时间:2023-09-26

在一个相当大的页面上,用户可以通过各种方式编辑数据: - 更改一些"经典"输入字段 - 通过单击按钮添加文件 - 通过拖放更改项目的顺序

在 HTML 中,简化的示例可能如下所示:

<form>
    Name: <input ng-model="person.name">
    Title: <input ng-model="person.title">
    Image: <our-custom-image-uploade-directive ng-model="person.image"/>
    Skills: <our-custom-skill-drag-and-drop-directive ng-model="person.skills"/>
    <button ng-click="save()">Save</button>
</form>

您会看到,有些编辑"设施"是基于表单的,有些则不是。

现在,有一个相当简单的任务要做:如果用户没有更改任何内容或碰巧最终获得与用户与数据交互之前完全相同的数据状态,请禁用"保存"按钮。

现在我想知道哪种是实现这一目标的最佳方法。

一种方法可能是深入观察整个人的对象。诸如此类:

$scope.backupCopyOfPerson = angular.copy($scope.person); // Creae a backup copy of the state before the user changed something
$scope.$watch('person', function (newValue) {
            if(newValue && $scope.backupCopyOfPerson) {
                if(angular.equals(newValue, $scope.backupCopyOfPerson)) {
                    $scope.unsavedChanges = false;
                }
                else {
                    $scope.unsavedChanges = true;
                }
            }
        }, true);

但是,深入观察具有大量子对象等的大型对象可能会导致一些严重的性能问题。

另一个想法是,将ng-pristine用于原版表单字段,并在所有其他指令等中使用。 $setDirty()/$setPristine() .这可能会更快,但这绝对不是一个优雅的解决方案。

你觉得怎么样?

角度版本是1.58

我对此的看法:

如果您对观看效果有疑问:您应该将角度表单检查与常规输入结合起来,并在其他属性上添加观察程序。

这将节省您的时间和性能,因为您将观看尚未显示的变量

$scope.$watch('person.image', function (newValue) {
      $scope.unsavedChanges.image = ($scope.person.image == $scope.backupCopyOfPerson.image)
}}, true);

然后在保存时检查您的unsavedChanges是否至少为 1 真