我正在学习angularjs,我遇到了一些我无法理解的行为。我在ng-repeat中渲染一个项目列表,每个项目都有一个从$ scope的数组中删除自己的按钮 - 这可以按预期工作,但是一旦我在列表中添加了一个可排序的奇怪事情就开始发生了。
以下是显示问题的运行示例:
https://embed.plnkr.co/eQWcxZ7p8CcACfk6Z53X/
在示例中 - 如果我将[^]项目4(火箭启动器)移动到位置1并使用Rocket Launcher的删除[X]按钮,则列表会更新(即项目4 - 火箭启动器 - 位于第1位的已删除)但其他项删除按钮停止工作。基本上移动项目并删除它们会以某种方式破坏绑定(?)。
(function() {
'use strict';
var app = angular.module('myApp', []);
app.controller('myAppController', function($scope) {
$scope.boxes = [];
$scope.removeBoxItem = function(box, item) {
console.log('Removing "' + item.name + '" form box "' + box.name + '"...');
var index = box.items.indexOf(item);
box.items.splice(index, 1);
console.log(box);
};
this.init = function() {
var e;
e = new Box({
name: 'Red box'
});
$scope.boxes.push(e);
e.items.push(new Item({
index: 1,
name: 'Rock'
}));
e.items.push(new Item({
index: 2,
name: 'Scissors'
}));
e.items.push(new Item({
index: 3,
name: 'Paper'
}));
e.items.push(new Item({
index: 4,
name: 'Rocket launcher'
}));
e = new Box({
name: 'Green box'
});
e.items.push(new Item({
index: 1,
name: 'Chuck the Plant'
}));
e.items.push(new Item({
index: 2,
name: 'Hamster'
}));
e.items.push(new Item({
index: 3,
name: 'Tentacle Chow'
}));
$scope.boxes.push(e);
};
this.init();
});
app.directive("sortable", ["$timeout", function($timeout) {
return {
template: '<div class="sortable" ng-transclude></div>',
transclude: true,
scope: {
'handle': '@'
},
link: function(scope, element, attrs) {
$timeout(function() {
//console.log(element)
var sortable = element.find('> div');
console.log(sortable[0]);
scope.sortable = Sortable.create(sortable[0], {
handle: scope.handle || null
});
});
}
};
}]);
}());
function Box(args) {
this.name = args.name || null;
this.items = [];
}
function Item(args) {
this.index = args.index || null;
this.name = args.name || null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
<style>
.container {
border: 1px solid #929292;
padding: 5px;
}
.header {
font-size: 1.2rem;
padding: 10px 15px;
background-color: #F5F5F5;
border-bottom: 2px solid #E2E2E2;
}
.body {
background-color: #F2F2F2;
padding: 10px 10px;
margin-bottom: 10px;
}
.body .item {
border: 1px solid #D2D2D2;
padding: 5px;
margin-bottom: 5px;
}
.body .options {
float: right;
}
.body .options .delete {
cursor: pointer;
}
.body .options .handle {
cursor: move;
}
.debug {
margin-top: 20px;
border-top: 1px dotted #929292;
}
</style>
</head>
<body>
<div ng-app="myApp" ng-controller="myAppController as appCtrl">
<div class="container">
<div ng-repeat="box in boxes">
<div class="header">{{ box.name }}</div>
<div class="body">
<div data-sortable="" data-handle=".handle">
<div class="item" ng-repeat="item in box.items">
{{item.index }}) {{ item.name }}
<div class="options">
<span ng-click="removeBoxItem(box, item)" class="delete">[X]</span>
<span class="handle">[^]</span>
</div>
</div>
</div>
</div>
</div>
<div class="debug">
<pre>{{ boxes | json }}
</pre>
</div>
</div>
</div>
<script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="Sortable.js@1.6.0" data-semver="1.6.0" src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.js"></script>
<script data-require="angular.js@1.6.6" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>
<script src="script.js"></script>
</body>
</html>
我对此感到困惑,在我的真实代码中,事情变得更加破碎 - 我制作了一个围绕“Boxes”的可折叠指令,因此我可以一次打开和操作一个 - 在这种情况下将项目4移动到位置1并删除它会从视图中删除所有项目(但不会从$ scope中删除)。将新项添加到$ scope的数组会导致项正确地重新出现。现在我创建了更简单的版本,因为我猜这都是以某种方式连接的。
我知道sortable应该设置对象索引等但是现在我想了解发生了什么。我怀疑我在理解范围内发生了什么问题(?)。非常感谢任何帮助。