#jquery #html #angularjs #jquery-ui
#jquery #HTML #angularjs #jquery-ui
Вопрос:
Я пишу сайт на Angular, используя пользовательский интерфейс jQuery, который позволяет упорядочивать элементы. Сначала я заполняю свой DOM содержимым массива, а затем разрешаю пользователю перетаскивать элементы DOM. Я хочу, чтобы перетаскивание элементов DOM соответствовало обновлению порядка массива.
Я использую ng-repeat
директиву для преобразования массива в DOM-дерево, и изначально думал, что перестановка элементов массива произойдет автоматически. Могу ли я сделать это с помощью Angular? Вот мой код:
<!DOCTYPE html>
<html ng-app = "">
<head>
<style>
#BlockContainer li
{
/*make there be no selection on each list item*/
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}
li
{
list-style-type: none;
}
#ArchtypeContainer li, #BlockContainer li
{
display: block;
}
</style>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" data-require="bootstrap-css@3.1.1" data-semver="3.1.1" />
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js" data-require="bootstrap@3.1.1" data-semver="3.1.1"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js" data-require="angular.js@1.2.17" data-semver="1.2.17"></script>
</head>
<body ng-controller="Controller">
<script>
function Controller($scope)
{
//sets out the data archtypes for everything
$scope.BlockArchtypes = [{"Name": "Move Seconds", "Arguments": [{"Placeholder": "Speed (0 - 100)"}, {"Placeholder": "Seconds"}]}, {"Name": "Move Distance", "Arguments": [{"Placeholder": "Distance (Feet)"}, {"Placeholder": "Speed (0 - 100)"}]}];
$scope.BlockData = [];
$scope.NewBlock = function (index)
{
$scope.ToCopy = angular.copy($scope.BlockArchtypes[index]);
$scope.BlockData.push($scope.ToCopy);
}
$scope.Update = function(){
console.log($scope.BlockData);
}
}
$(document).ready(function()
{
$("#BlockContainer").sortable(
{
change: function(event, ui)
{
$scope.apply($scope.BlockData);
}
});
});
</script>
<h3>Archtypes</h3>
<ul id = "ArchtypeContainer">
<li ng-repeat="Block in BlockArchtypes">
<div>{{Block.Name}}</div>
<div ng-repeat="Argument in Block.Arguments"><input type="text" ng-model = "Argument.Value" placeholder="{{Argument.Placeholder}}" /></div>
<button ng-click = "NewBlock($index);">Add</button>
</li>
</ul>
<h3>Program</h3>
<button ng-click = "Update()">Update</button>
<ul id = "BlockContainer">
<li ng-repeat="Block in BlockData track by $index">
<div>{{Block.Name}}</div>
<div ng-repeat="Argument in Block.Arguments"><input type="text" ng-model = "Argument.Value" placeholder="{{Argument.Placeholder}}" /></div>
</li>
</ul>
</body>
</html>
Ответ №1:
Вероятно, это лучший способ использовать библиотеку перетаскивания для AngularJS, которая в основном является перетаскиваемой в jQuery UI, но предназначена для работы непосредственно с Angular.
Перетаскиваемый пример:
<div class="btn btn-primary" data-drag="true" data-jqyoui-options="{revert: 'invalid'}"
ng-model="list1" jqyoui-draggable="{animate:true}" ng-hide="!list1.title">
{{list1.title}}
</div>
Удаляемый пример:
<div class="thumbnail" data-drop="true" data-jqyoui-options ng-model="list2"
jqyoui-droppable style='height:50px;'>
<div class="btn btn-success" data-drag="false" data-jqyoui-options ng-model="list2"
jqyoui-draggable ng-hide="!list2.title">
{{list2.title}}
</div>
</div>
Угловой код:
App.controller('OverviewCtrl', function($scope) {
$scope.list1 = {title: 'AngularJS - Drag Me'};
$scope.list2 = {};
});
В Интернете есть еще примеры.
И причина, по которой вы не заставили его работать с jQuery UI, заключается в том, что Angular не знает об изменениях DOM, если только изменения не были сделаны самим Angular, или вы не сообщили ему об изменениях (например, через $ scope.$apply()))… Итак, чтобы все это заработало, вам нужно было бы прикрепить наблюдатели или создать функции обратного вызова ко всем подвижным элементам и заставить Angular выполнять необходимые обновления переменных области видимости при каждом изменении — вот почему я предложил эту библиотеку, она делает практически все за вас.