Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.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 使用angular$resource.save保存会导致视图由于收集监视程序而重新绘制/回流_Javascript_Angularjs - Fatal编程技术网

Javascript 使用angular$resource.save保存会导致视图由于收集监视程序而重新绘制/回流

Javascript 使用angular$resource.save保存会导致视图由于收集监视程序而重新绘制/回流,javascript,angularjs,Javascript,Angularjs,我有一个使用$resource加载和存储的模型。该模型是一个聚合,其中包含嵌套的集合,这些集合使用ng repeat绑定到html视图 型号: { someRootField: "blabla", sectionCollection: [ { name: "section1" .... }, { name: "section2", ...

我有一个使用$resource加载和存储的模型。该模型是一个聚合,其中包含嵌套的集合,这些集合使用ng repeat绑定到html视图

型号:

{
    someRootField: "blabla",
    sectionCollection: [
        {
            name: "section1"
            ....
        },
        {
            name: "section2",
            ....
        }
    ]
}
html:

问题是:当我在这个模型上使用$save时,它会导致重新加载/重画屏幕的某些部分(似乎不是根字段,而是与集合相关的字段),如果部分中的一些绑定元素是输入,那么焦点也会丢失。我做了一些调试,下面是我认为正在发生的事情

  • 当我保存模型时,POST命令的结果镜像了请求的主体,myModel将被重新填充。模型根中的简单字段几乎相同,因此watch()机制不会检测到其中的更改,但是sectionCollection数组中的对象不同,因为它们不是通过内容进行比较,而是通过引用的相等性进行比较,结果失败,这将导致与集合关联的ui控件完全重新加载/绘制
  • angular中的$watchCollectionWatch()中有以下代码:

          } else if (isArrayLike(newValue)) {
            if (oldValue !== internalArray) {
              // we are transitioning from something which was not an array into array.
              oldValue = internalArray;
              oldLength = oldValue.length = 0;
              changeDetected++;
            }
    
            newLength = newValue.length;
    
            if (oldLength !== newLength) {
              // if lengths do not match we need to trigger change notification
              changeDetected++;
              oldValue.length = oldLength = newLength;
            }
            // copy the items to oldValue and look for changes.
            for (var i = 0; i < newLength; i++) {
              if (oldValue[i] !== newValue[i]) {
                changeDetected++;
                oldValue[i] = newValue[i];
              }
            }
          }
    
    }else if(类似isArrayLike(newValue)){
    if(oldValue!==内部数组){
    //我们正在从不是数组的东西过渡到数组。
    oldValue=内部数组;
    oldLength=oldValue.length=0;
    changeDetected++;
    }
    newLength=newValue.length;
    if(oldLength!==newLength){
    //如果长度不匹配,我们需要触发更改通知
    changeDetected++;
    oldValue.length=oldLength=newLength;
    }
    //将项目复制到oldValue并查找更改。
    对于(变量i=0;i
    在我的例子中,我肯定看到oldValue[I]=newValue[I]比较失败,对象是不同的。原因之一是oldValue包含的变量前缀为$,这些变量引用了以前为每个项创建的作用域

    问题是,如何防止回流?或者我该如何做才能避免它。为自己保留两个模型副本,一个用于$resource,另一个用于绑定到视图并手动在它们之间进行同步,这似乎是不对的

    谢谢

    您可以使用该服务来避免$save原因导致的模型更新:

    $scope.save2 = ->  $http.get 'blah_new.json'
    
    我在示例中使用了
    get
    ,但您可以从中使用任何您需要的内容。这里有一个简单的例子

    此外,在重播后保存elemen的焦点也很简单:

      $scope.save = -> 
        active = document.activeElement.getAttribute 'id'
        $scope.user1.$save ->
          document.getElementById(active).focus()
    

    让您在plnkr上编写示例代码会非常方便。co$save将更新您的模型,因此模板应该重新提交-为什么这对您来说是个问题?当模板重新提交时,图像会重新加载,如果涉及表单输入,它们会失去焦点。除非您没有数千次保存操作,也许图像重播没什么大不了的?此外,您还可以在保存元素之前使用焦点记住它,并在保存之后恢复它。不管怎样,你们都可以使用$http,正如我在下面的回答中所示。我修改了你们的框架,使之更像我的案例。尝试编辑其中一个好友,然后按TAB键将焦点移动到下一个字段。我没有检查,但我怀疑此解决方案存在缺陷-它不会将元素重新聚焦到用户所在的光标位置。
    $scope.save2 = ->  $http.get 'blah_new.json'
    
      $scope.save = -> 
        active = document.activeElement.getAttribute 'id'
        $scope.user1.$save ->
          document.getElementById(active).focus()