2013-03-18 12 views
7

Jestem nowym użytkownikiem Angular i próbuję utworzyć dyrektywę, która będzie wiązała pozycję elementu do modelu - po przeciągnięciu przez użytkownika . Znalazłem jeszcze jedno pytanie przepełnieniem stosu, który rozwiązuje ten problem za pomocą prostego obiektu:Oprawa atrybutów Angularjs powiązana z lewej/górnej pozycji po przeciągnięciu z powtórzeniem ng

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 rozwiązanie tutaj: http://jsfiddle.net/mrajcok/5Mzda/

Teraz jestem teraz stara się uzyskać to do pracy z bardziej obiekt złożony i z ng-repeat, ale nie może wydawać się zrozumieć, dlaczego nie działa.

Tu jest mój 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> 

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

Oto Fiddle:

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

ja nie potrafię zobaczyć co jest nie tak z kodem. Doceniam każdą pomoc!

UPDATE

ja dokładniej przeczytać komentarze na oryginalne pytanie, i wygląda na to, używając $eval prace:

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

Nie wiem, czy istnieje bardziej elegancki sposób to zrobić, ale wydaje się, że bindowanie działa teraz poprawnie!

Odpowiedz

7

To wygląda dobrze.

Musisz wykonywać wszystkie wyrażenia powiązane z kątami w ramach kątowej. W przypadku programów obsługi zdarzeń w domenie i metod wywoływanych spoza programów obsługi zdarzeń, należy wykonać je w trybie kątowym przy użyciu $apply, który wykona wyrażenie, a następnie zadzwoni pod numer $digest, który z kolei wywoła dołączone zegarki.

Jedyną zmianą trzeba zrobić jest przeniesienie oświadczenia wewnątrz $apply()

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

Demo: Fiddle

+0

Nicea ryba, to był pomocny. – jcollum

Powiązane problemy