Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度资源-如何检查资源实例是否有任何未保存的更改?_Javascript_Angularjs_Angularjs Service_Angularjs Resource - Fatal编程技术网

Javascript 角度资源-如何检查资源实例是否有任何未保存的更改?

Javascript 角度资源-如何检查资源实例是否有任何未保存的更改?,javascript,angularjs,angularjs-service,angularjs-resource,Javascript,Angularjs,Angularjs Service,Angularjs Resource,我想知道用户是否修改了$resource实例,也就是说,它的当前状态是否与最初从服务器加载的状态不同&尚未保存$resource实例。如何实现这一点?假设您获得一个资源,然后将其放在当前的$scope上,以便用户可以编辑它: $scope.question = Questions.get({id:"19615328"}); 然后,您可以观察它是否有如下变化: // some flag, name it anything $scope.userChange = false; $scope.$wa

我想知道用户是否修改了$resource实例,也就是说,它的当前状态是否与最初从服务器加载的状态不同&尚未保存$resource实例。如何实现这一点?

假设您获得一个资源,然后将其放在当前的$scope上,以便用户可以编辑它:

$scope.question = Questions.get({id:"19615328"});
然后,您可以观察它是否有如下变化:

// some flag, name it anything
$scope.userChange = false;
$scope.$watch('question', function(newValue, oldValue) {
    if(newValue && newValue != oldValue){
        $scope.userChange = true;
        // if you want to you can even do this, this will trigger on every change though
        $scope.question.$save();
    }
}, true);
(下面的所有内容都是下面聊天的额外问题的结果)

然后,每当您想检查它是否已更改时,
$scope.userChange
可以告诉您是否发生了更改。保存对象时,重置
$scope.userChange

你甚至可以这样做

$scope.$watch('question', function() {
    $scope.question.$save();
}, true);
显然,您希望添加某种节流或“去盎司”系统,以便它等待一秒钟左右,一旦您将此设置到位,对对象的任何更改都将导致通过
$scope.$watch
进行保存

如果您想检查null,当您还没有收到实际对象时

$scope.$watch('question', function(newValue, oldValue) {
    // dont save if question was removed, or just loaded
    if(newValue != null && oldValue != null){
        $scope.question.$save();
    }
}, true);
你甚至可以把
问题包装起来。让
打电话,看看,这样做

Questions.getAndAutosave = function(options){
    var instance = Questions.get(options);
    $scope.$watch(function(){
            return instance;
        },
        function(newValue, oldValue){
            if (newValue === oldValue) return;
            if(newValue != null && oldValue != null){
                instance.$save();
            }
        }, true);
    return instance;
};

然后,无论何时调用
Questions.getAndAutosave
,它返回的任何内容都已被监视,并将自动保存。如果(newValue==oldValue)返回,则执行
的原因
是因为
$watch
会在您调用它时立即激发,然后监视更改。我们不需要在第一次呼叫时保存数据。

我发现了一种解决方案,它既不将从服务器下载数据视为用户更改,也直接在服务本身中实现。它可能不是最有效的解决方案,但提供了我想要的功能

app.factory('testService', ['$resource', '$rootScope', function($resource, $rootScope){
var test = $resource('/api/words/:id', {id: '@id'});

test.orig_get = test.get;

test.get = function(options){
    var instance = test.orig_get(options, function(){
        instance.unsaved = false;
        $rootScope.$watch(function(){
            return instance;
        }, function(newValue, oldValue) {
           if(angular.equals(newValue, oldValue)){
                return;
           }
           var changed_indexes = [];
           for(var i in newValue){
                if(!angular.equals(newValue[i], oldValue[i])){
                    changed_indexes.push(i);
                }
           }
           if(newValue != null && oldValue != null && !(changed_indexes.length==1 && changed_indexes[0]=='unsaved')){
                console.log('detected change. setting unsaved to true');
                instance.unsaved = true;
            }

        }, true);
    });
    return instance;
}

test.prototype.orig_save = test.prototype.$save;

test.prototype.$save = function(options){
    return this.orig_save(options, function(){
        this.unsaved = false;           
    })
}

return test;
}]);

您可以克隆初始对象,然后在需要检查时进行比较

master = null
resource = Resource.get({id:1}, function() {
  master = angular.copy(resource)
})
function isModified() {
  return !angular.equals(resource, master)
}

不幸的是,在执行$get时,$watch也会被触发,因为$scope.question会从null变为object。。。我想要的东西只有在用户做出更改时才会报告未保存的更改,而不是在从服务器提取数据时。其想法是在收到响应后再进行查看。或给$watch第二次回调(接收新旧值),以便检查旧值是否为null。(或者如果新值为null?:-)同样,您认为这样的功能可以直接在服务中实现吗?我知道我可以用附加功能来扩充$resource。在每个控制器中为每个资源实现这些功能可能会很乏味,而且远不是很优雅。我已经添加了一个关于您可以做什么的简短示例,还有一个关于如何在服务/工厂级别配置它的问题,有很多选项。出于某种原因,
if(newValue!=null&&oldValue!=null){
在$watch中的条件是不够的。我已经实现了它,并且在资源加载后立即将$scope.userChange标志设置为true,即使用户还没有对对象进行任何更改。关于如何更正这一点,您有什么想法吗?虽然这解决了问题,但对对象进行比较非常昂贵。如果在视图中使用这样的函数,这种昂贵的比较算法将在每个摘要周期中运行,使应用程序运行缓慢。