【问题标题】:Scope confusion in ng-grid when returning data from modal从模态返回数据时ng-grid中的范围混淆
【发布时间】:2014-07-12 10:19:29
【问题描述】:

这是 Plunker:http://plnkr.co/edit/aqLnno?p=preview

我有一个要显示在 ng-grid 中的人员列表 ($scope.persons)。每行都有一个编辑按钮。当用户单击按钮 (ng-click="edit(row)")(参见下面的代码)时,我复制显示的人 (angular.copy(row.entity)) 并打开一个模式对话框。 ...到目前为止一切顺利。

当用户在模式上单击“取消”时,什么也没有发生。当用户在模型上点击“保存”时,修改后的人会被返回,应该在$scope.persons中“重新整合”。

这就是问题的开始:我在$scope.persons 中搜索以找到正确的人并将其替换为从模态返回的人。日志语句显示修改前后的$scope.persons,一切看起来都很好。但是,ng-grid 似乎并不在意。它仍然在不同的(旧的)$scope.persons 上运行。

如果我取消注释 row.entity = person 并直接设置行,那么在 ng-grid 中一切看起来都很好。但是,由于底层数据模型没有正确更改,因此度假村将再次调出旧的(未修改的)人。

这是我的编辑功能的代码:

$scope.edit = function(row) {
  $modal.open({
    templateUrl: 'personEdit.html',
    backdrop: true,
    windowClass: 'modal',
    controller: 'PersonModalInstanceCtrl',
    resolve: {
      person: function() {
        return angular.copy(row.entity);
      }
    }
  })
    .result.then(function(person) {
      $log.log('Edited person: ' + JSON.stringify(person));
      angular.forEach($scope.persons, function(p, index) {
        $log.log('p: ' + JSON.stringify(p) + ' index: ' + index);
        if (p.id == row.entity.id) {
          $log.log('scope: ' + JSON.stringify($scope.persons));
          $scope.persons[index] = person;
        }
      });
      $log.log('scope: ' + JSON.stringify($scope.persons));
      // row.entity = person;
    }, function() {});
};

我的示波器做错了什么?

感谢您的帮助

【问题讨论】:

  • 在插件中找不到按钮
  • 编辑按钮位于 personCellTemplate.html 中,它作为附加列包含在 $scope.gridOptions 中的 ColumnDefs 中:{field: 'Actions', cellTemplate: 'personCellTemplate.html'}。但这部分有效:模式打开,可以进行编辑,并且它确实正确返回了编辑后的人。
  • 它说的是ReferenceError: $modal is not defined
  • plnkr.co/edit/aqLnno?p=preview 对我有用...(好吧,我可能搞砸了冻结按钮。现在可以工作了吗???)

标签: angularjs angularjs-scope ng-grid


【解决方案1】:

好的。又学到了一些东西。 jantimon的回答为我指明了正确的方向。但我不喜欢他如何更改我的 $scope.persons 数组(我从 RESTful GET 中获得了这个数组,并且喜欢我可以直接将返回的 JSON 用作 $scope.persons 而无需修改)。

不管怎样,解释如下:

从原始 $scope.persons 列表中复制我的人时,我在新的内存位置创建了一个新对象:

angular.copy(row.entity)

这是必要的,因为用户可以“取消”他的编辑。

当用户点击“保存”时,我必须把这个复制的人放回 $scope.persons 而不是旧的。我这样做了:

$scope.persons[index] = person;

虽然这是正确的并且给出了期望的结果(如日志语句所示),但 people[index] 现在指向不同的内存位置。

但是:ng-grid 内部仍然指向旧的内存位置! ng-grid 没有将指针 (person[index]) 记住为数据模型,而是记住了原始指针 (*person[index]) 的目的地 [对不起我的 C 风格谈话]。我会认为这是 ng-grid 恕我直言的 BUG。

所以我需要做的就是将新人复制回它来自的完全相同的内存位置。幸运的是,有一个角度指令:

angular.extend($scope.persons[index], person);

如果你只是替换 $scope.persons[index] = person;使用 angular.extend($scope.persons[index], person);一切正常。

【讨论】:

  • 有没有快速搜索 $scope.persons 中人物索引的方法?
  • 我只是遍历数组以找到合适的人 (angular.forEach) .. 效率不高但有效,我的数组最多有几百人(通常少得多)。跨度>
  • 啊,我也在做同样的事情,但想问一下,只是为了确保其他人在做同样的事情(O(n)搜索)......必须有搜索功能而不写完整的,不是吗?就像在 C# 中你有 LINQ 并且你一直停止编写 fors,例如:someArray.Where(e => e.personId == id)
  • 好吧,我并不是真正的 JavaScript 人。但是应该有类似 HashMap 的东西,可以让你 O(1) 访问正确的人......
  • 是的,javascript 中的每个列表也可以用作地图...但是对于这种情况,underscore.js 可能会有所帮助(这是我的结论)
【解决方案2】:

当您更改数组时,看起来 ng-grid 没有正确更新

您可以像在此示例中一样保留行实体的指针:http://plnkr.co/edit/0lDoKOg4kXXa51NlSuMg?p=preview

它使用$scope.persons[index].data = person.data; 而不是$scope.persons[index] = person;

【讨论】:

  • 嗯。这个确实有效。谢谢你。但我不知道为什么。正如您可能猜到的那样,我将我的人作为一个安静的 GET 来返回一个 JSON 对象数组,奇怪的是我必须通过引入“数据”字段来重新排列这个结构。
  • 我不喜欢我必须更改从我的 REST 服务获得的 people 数组的事实。但是您的回答为我指明了正确的方向(请参阅我自己的回答)。没有你就不会找到它。谢谢! ...您是否同意所描述的行为是 ng-grid 中的错误?我来自 Java/C/C++ 背景,Javascript 和 Angular 对我来说是新的......
  • 提交一个错误 - 这是 Angular 可以处理的,所以 ng-grid 也应该支持它:plnkr.co/edit/JNGh7mjU8WqeNG3RHbiM?p=preview
猜你喜欢
  • 2011-10-13
  • 2020-06-13
  • 2020-02-16
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
相关资源
最近更新 更多