使用ng-repeat拖动后,Angularjs指令属性绑定左/上位置

时间:2013-03-18 06:07:59

标签: javascript binding angularjs

我是Angular的新手,并且一直在尝试创建一个指令,该指令将元素上的位置绑定到模型上 - 在用户拖动之后。我找到了另一个Stack Overflow问题,它解决了一个简单的对象:

Angularjs directive attribute binding of left and top position after dragging

myApp.directive('draggable', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.draggable({
                cursor: "move",
                stop: function (event, ui) {
                    scope[attrs.xpos] = ui.position.left;
                    scope[attrs.ypos] = ui.position.top;
                    scope.$apply();
                }
            });
        }
    };
});

请参阅此处的小提琴解决方案:http://jsfiddle.net/mrajcok/5Mzda/

现在,我正在尝试使用更复杂的对象并使用ng-repeat,但似乎无法弄清楚为什么它不起作用。

这是我的HTML:

<div ng-controller="MyCtrl">
  <div ng-repeat="position in positions">
      <input type="number" ng-model="position.divleft"/>
      <input type="number" ng-model="position.divtop"/>
      <p draggable class="example" ng-style="{left: position.divleft, top: position.divtop}" xpos="position.divleft" ypos="position.divtop">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </div>
</div>

这是JS:

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
  $scope.positions = [
      {"divtop": 80,
       "divleft": 200
      },
      {"divtop": 100,
       "divleft": 250
      }
  ];
};

myApp.directive('draggable', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.draggable({
                cursor: "move",
                stop: function (event, ui) {
                    scope[attrs.xpos] = ui.position.left;
                    scope[attrs.ypos] = ui.position.top;
                    scope.$apply();
                }
            });
        }
    };
});

这是小提琴:

http://jsfiddle.net/5Mzda/19/

我似乎无法看到代码有什么问题。非常感谢任何帮助!

更新

我在原始问题中更仔细地阅读了评论,看起来好像使用了$eval

myApp.directive('draggable', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.draggable({
                cursor: "move",
                stop: function (event, ui) {
                    scope.$eval(attrs.xpos + '=' + ui.position.left);
                    scope.$eval(attrs.ypos + '=' + ui.position.top);
                    scope.$apply();
                }
            });
        }
    };
});

不确定是否有更优雅的方法可以做到这一点,但现在看来绑定工作正常了!

1 个答案:

答案 0 :(得分:7)

看起来很好。

您需要在角度框架中执行所有与角度相关的表达式。对于从事件处理程序外部调用的dom事件处理程序和方法,您需要使用角度$apply执行它们,这将执行表达式,然后调用$digest,而Fiddle依次将打电话给附上的手表。

您必须做的唯一更改是移动$apply()

中的语句
scope.$apply(function(){
    scope.$eval(attrs.xpos + '=' + ui.position.left);
    scope.$eval(attrs.ypos + '=' + ui.position.top);
});

演示:{{3}}