简体   繁体   中英

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

On a rather big page a user can edit data in various ways: - Change some "classical" input fields - Add files via clicking on a button - Change the order of items via drag and drop

In the HTML, a simplified example might look like such:

<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>

You see, some edit "facilities" are form-based, some are not.

Now, there is a rather simple task to do: Disable the "save" button if the user didn't change anything or happened to end up with the very same state of data that it was before the user interacted with the data.

Now I'm wondering which is the best way to achieve that.

One way might be to deep watch the whole person object. Like that:

$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);

However, deep watching a big object with a lot of sub-objects etc. might cause some serious performance issues.

Another idea is, using ng-pristine for the vanilla form fields and do in all other directives etc. $setDirty() / $setPristine() . That might be faster, but it's definitely not an elegant solution.

What do you think?

Angular version is 1.58

My take on this:

If you have issue with the watching performance: You should combine angular form checking for regular input, and add a watcher on the other attributes.

This will save you time & performances as you will watch the variable that are not already

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

and then upon save check if your unsavedChanges as at least 1 true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM