简体   繁体   中英

Use angular to mark modified elements in a list

I want to synchronize data, therefore I have a data object containing the current state. When this is changed I would like to set an attribute on the object so that I can filter by this when syncing. The object structure is:

data = {  
type1: [  
  {a:"a", b:"b"},...  
]  
type2: [  
  {c:"c", d:"d"},...  
]  
}  

For example if data.type1[0].a = "test" would be done, I would like to add modified: true to the object so that it would be

{a:"test", b:"b", modified:true}

I have tried $watch(data, function(), true) but I can not find how I can see which object was changed and searching both given data objects would be a large overhead. $watchcollection (when just looking for adding/deleting) also does not give an index.
Is there any way to find out which object was changed? Or is there an other library which can do this well?

Thank you

EDIT:
I created a jsfiddle: https://jsfiddle.net/yfo8xwah/

Although this is a silly workaround but what you can do is to keep a method in data object like :

data = {type1 : {}, type2 : {}, ... , checkModification : function (field)
{data[field].modified = true; return data[field];}}

Now You can assign any object like this data.checkModification('type1').a = "test" This may give you satisfactory result.

Ok, I had made it work: https://jsfiddle.net/yfo8xwah/4/ .

First of all I have applied a simple watcher on the data model. Inside the watcher I have used this beautiful library for object comparing and matching any differences and inject the modification flag.

So my $watch function looks like this:

$scope.$watch(function () {
        return $scope.data;
    }, function (newD, oldD, scope) {
        //dont run on init mate ;)
        if (angular.equals(newD, oldD)) {
            return;
        }
        //now find the differences and apply em
        var diffs = objectDiff.diffOwnProperties(newD, oldD);
        console.log(diffs, "diffs");

        if (diffs.changed != "equal") {
            //you should solve this recursively ;)
            angular.forEach(diffs.value, function (value, key) {
                if (value.changed != "equal") {
                    angular.forEach(value.value, function (subvalue, subkey) {
                        if (subvalue.changed != "equal") {
                            $scope.data[key][subkey]["modified"] = true;
                        }
                    });
                }
            });
        }

    }, true);

After considering the different options, I decided that it was necessary to use custom getters/setters.

This is necessary as no real event handler exists and it would be very inefficient to always compare the whole data set (which might have a few thousand elements).

I think this will help ......

 var app = angular.module('sample', []); app.controller("MyAppCtrl", function ($scope, $timeout) { $scope.data = { type1: [{ a: "a", b: "b" }, { a: "c", b: "d" }], type2: [{ m: 0, k: 1 }, { m: 45, k: 92 }] } $scope.$watch('data.type1[0].a', function () { console.log('data changed'); $scope.data.type1[0].modified = true; console.log($scope.data.type1[0]) }); }); 
 <body ng-app="sample"> <div ng-controller="MyAppCtrl"> <input type="text" ng-model="data.type1[0].a"> <br> <label>{{data.type1[0].a}}</label> </div> </body> 

https://jsfiddle.net/basilin/p92Lkn93/

Try it. Whenever particular object's property change by input like textbox

Than on change event pass that object to this function like below:

<input  data-ng-model="data.type1.a" type="text" 
        data-ng-change="onChage(data.type1)"/>
        $scope.onChage = function (object) {
            object.IsDirty = 'modified';
        };

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