AngularJS:在ng-repeat中更新父作用域的指令

3
我有一个自定义的可拖动指令,放在图片的ng-repeat中。我想在每个图片被拖动后存储它的x,y偏移量。因此,我需要该指令更新图片上的一个字段。
return {
    restrict: 'A',
    scope: false,
    link: function(scope, element, attrs){
        element.draggable({
            containment: "parent",
            cursor: "crosshair",
            stop: function(ev, ui) {
              scope.left=ui.helper[0].style.left;
              scope.top=ui.helper[0].style.top;
          }
       });
     }
  };

  <div ng-repeat="image in images" 
       draggable
       ng-style="{left:image.left,
                 top:image.top}">... image stuff here ...</div>

很遗憾,这并不起作用,因为当ng-repeat为每个图像项创建子作用域时,它会创建一个新的作用域,该作用域从父作用域继承,但它还将项目的值分配给子作用域上的一个新属性。(新属性的名称是循环变量的名称。)(https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-repeat
通过更改引用以使用循环变量名称,我可以使指令按照我的意愿工作。
scope.image.left=ui.helper[0].style.left;
scope.image.top=ui.helper[0].style.top;

但我不想将循环变量名称硬编码到指令中。

传递循环变量名称到指令的最佳方法是什么?或者,理想情况下,直接将项目值的引用传递给指令?

1个回答

2
在这种情况下,使用隔离作用域并使用双向绑定将当前图像对象传递到指令中是很方便的。
因此,HTML可以像这样:
<div ng-repeat="image in images" draggable="image" ng-style="{left:image.left, top:image.top}">
    <!-- ... image stuff here ... -->
</div>

如果有指令,则:

.directive('draggable', function () {
    return {
        scope: {image: '=draggable'},
        link: function (scope, element, attrs) {
            element.draggable({
                containment: "parent",
                cursor: "crosshair",
                stop: function (ev, ui) {
                    scope.image.left = ui.helper[0].style.left;
                    scope.image.top = ui.helper[0].style.top;
                }
            });
        }
    };
});

这样你就不再硬编码变量名,使指令更具可重用性。例如,你可以将HTML更改为ng-repeat="img in images" draggable="img",但指令代码将保持不变。


1
这对我来说没有使用digest也可以工作。=draggable正是我正在寻找的,谢谢! - alisonmsmith
@PankajParkar 在这里不需要使用摘要,因为您直接修改对象属性,可以利用直接对象引用的优势。 - dfsq
@dfsq 我在想,像 stop 这样的事件,我们是通过事件来操作作用域的,那么 Angular 是如何知道我应该触发 digest 呢? - Pankaj Parkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接