2013-03-18 2 views
7

Ich bin neu in Angular und habe versucht, eine Direktive zu erstellen, die die Position eines Elements an ein Modell bindet, nachdem es vom Benutzer gezogen wurde . Ich fand einen anderen Stack-Überlauf Frage, die diese für ein einfaches Objekt löst:Angularjs Direktivenattribut Bindung links/oben nach dem Ziehen mit ng-repeat

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

See Fiddle Lösung hier: http://jsfiddle.net/mrajcok/5Mzda/

Jetzt versuche ich jetzt zu bekommen diese mit mehr zu arbeiten komplexes Objekt und mit ng-repeat, aber kann nicht herausfinden, warum es nicht funktioniert.

Hier ist mein 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> 

Und hier ist die 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(); 
       } 
      }); 
     } 
    }; 
}); 

Hier ist der Fiddle ist:

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

Ich kann nicht scheinen, um zu sehen, Was stimmt nicht mit dem Code? Würde mich über jede Hilfe freuen!

UPDATE

las ich die Kommentare enger in der ursprünglichen Frage, und es sieht aus wie $eval Arbeiten mit:

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

nicht sicher, ob eine elegantere Möglichkeit gibt, dies zu tun, aber es scheint, die Bindung funktioniert jetzt richtig!

Antwort

7

Das sieht gut aus.

Sie müssen alle winkelbezogenen Ausdrücke im Winkelrahmen ausführen. Im Fall von dom-Event-Handlern und -Methoden, die von außerhalb der Event-Handler aufgerufen werden, müssen Sie sie im Winkel mit $apply ausführen, die den Ausdruck ausführen und dann $digest anrufen, die wiederum die angeschlossenen Uhren aufrufen wird.

Die einzige Änderung, die Sie machen müssen, ist, die Anweisungen in $apply()

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

Demo zu bewegen: Fiddle

+0

Nizza Geige, das war hilfreich. – jcollum

Verwandte Themen