简体   繁体   English

AngularJS:指令更新ng-repeat内的父范围

[英]AngularJS : Directive updating parent scope inside of ng-repeat

I have a custom draggable directive inside of an ng-repeat of images. 我在图像的ng-repeat中有一个自定义可拖动指令。 I want to store the x,y offset of each image after it has been dragged. 我想在拖动每个图像后存储x,y偏移量。 Therefore, I need the directive to update a field on the image. 因此,我需要指令来更新图像上的字段。

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>

Unfortunately, this doesn't work, because when ng-repeat creates the child scope for each image item, it 不幸的是,这不起作用,因为当ng-repeat为每个图像项创建子范围时,它

creates a new scope, which prototypically inherits from the parent scope, but it also assigns the item's value to a new property on the child scope. 创建一个新的作用域,它原型继承自父作用域,但它也将该项的值赋给子作用域的新属性。 (The name of the new property is the loop variable's name.) ( https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-repeat ) (新属性的名称是循环变量的名称。)( https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-repeat

I can get the directive to work as I want it to by changing the reference to use the loop variable name: 我可以通过更改引用来使用循环变量名来使指令工作,因为我想要它:

scope.image.left=ui.helper[0].style.left;
scope.image.top=ui.helper[0].style.top;

but I don't want to hardcode the loop variable name into the directive. 但我不想将循环变量名称硬编码到指令中。

What is the best way to pass the loop variable name to the directive or to, ideally, pass the reference to the item value to the directive directly? 将循环变量名称传递给指令或理想情况下,将项目值的引用直接传递给指令的最佳方法是什么?

In this case it is convenient to use isolated scope and pass current image object into directive using two-way binding. 在这种情况下,使用隔离范围并使用双向绑定将当前图像对象传递给指令是很方便的。

So HTML can be something like this: 所以HTML可以是这样的:

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

and directive then: 和指令然后:

.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;
                }
            });
        }
    };
});

This way you no longer hardcode variable name and make directive more reusable. 这样您就不再对变量名称进行硬编码,并使指令更具可重用性。 You can for example change HTML to ng-repeat="img in images" draggable="img" but directive code will stay the same. 例如,您可以将HTML更改为ng-repeat="img in images" draggable="img"但指令代码将保持不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM