当我在输入框中输入时,我有一个数组被过滤/搜索。当我点击返回时,输入文本被附加到数组。这一切都很棒,而且很有效。
什么是无效的是$ scope.list.indexOf()== -1,它应该阻止我输入重复项。但它不起作用。
我哪里错了?
HTML
<!doctype html>
<html ng-app="bgApp">
<head>
<title>List & Tag</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- Local CSS -->
<link rel="stylesheet" type="text/css" href="./static/css/dev-style.css" />
</head>
<body>
<div ng-controller="listController">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 div-title">
<div class="col-xs-6 col-sm-6 col-md-6">
<h1><small>{{title}}</small></h1>
<input type="text" ng-enter="addItem()" ng-model="addName" class="search-query" placeholder="Search">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 div-title">
<div class="col-xs-3 col-sm-3 col-md-3">Name of Item</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 div-row" ng-repeat="item in list | filter:addName">
<div class="col-xs-3 col-sm-3 col-md-3">{{ item.name }}</div>
</div>
</div>
</div>
<!-- AngularJS scripts from CDN -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-resource.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-animate.min.js"></script>
<!-- JQuery scripts from CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<!-- Bootstrap scripts compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<!-- Locally installed scripts -->
<script src="./js/bgapp.js"></script>
</body>
</html>
APP,指令&amp;控制器
var bgapp = angular.module('bgApp', [])
.directive('ngEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$eval(attrs.ngEnter, {
'event': event
});
});
event.preventDefault();
}
});
};
});
bgapp.controller('listController', ['$scope', function($scope) {
$scope.title = 'Recent Activity';
$scope.list = [
{name: 'User 1'},
{name: 'Admin 1'},
{name: 'Service 1'},
{name: 'Project 1'},
{name: 'Configuration Item 1'},
{name: 'Task 1'},
{name: 'Incident 1'},
{name: 'Issue 1'},
{name: 'Known Issue 1'},
{name: 'Problem 1'},
{name: 'Knowledge Base 1'},
{name: 'Update 1'},
{name: 'Document 1'},
];
$scope.addItem = function() {
var elem = {name: $scope.addName};
if ($scope.list.indexOf(elem) == -1) {
$scope.list.push(
elem
);
}
};
}]);
答案 0 :(得分:1)
由于$scope.list
是Object
的列表,因此测试$scope.list.indexOf(elem)
适用于2 Object
的引用,这些引用始终是不同的。
您可以使用AngularJS中的$filter('filter')(array, expression, comparator)
:
$scope.addItem = function() {
var elem = {name: $scope.addName};
if ($filter('filter')($scope.list, {name: elem.name}).length == 0) {
$scope.list.push(
elem
);
}
};
答案 1 :(得分:1)
Javascript不认为对象是相同的,因为它们不是同一个实例。 This link很好地解释了。
我建议使用下划线的findWhere来测试是否存在具有相同属性的对象。
在你的情况下:
if (_.findWhere($scope.list, elem) === undefined){
$scope.list.push(elem);
}
当然,您需要包含下划线才能使用它。由于您正在使用角度,因此您可能希望使用此:
答案 2 :(得分:0)
远离计算机,所以我采取了刺,但似乎你正在尝试对某个对象(项目列表)执行字符串操作。
答案 3 :(得分:0)
$scope.addItem = function() {
var elem = {name: $scope.addName};
if ($scope.listHasElement($scope.list, elem)) {
$scope.list.push(elem);
}
};
$scope.listHasElement = function (list, new) {
for (index = 0; index < list.length; ++index) {
if(list[index].name == new.name) return true;
}
return false;
}
试试这个,我现在无法测试它,但我猜它是问题的解决方案。
答案 4 :(得分:0)
您当前的indexOf
失败了,因为没有两个对象是相同的,除非它们是相同的引用,即{} !== {}
但是var o = {}; o === o;
在您尝试查找引用时,了解对象最初是如何创建的,并且 Object 可以序列化为JSON而不会抛出错误,您可以使用最后一个点来执行{{ 1}}用于字符串而不是
例如,使用Array.prototype.map
indexOf
你也可以类似地使用Array.prototype.some
,它可以在第一场比赛结束时(相对于上面的function serialisedIndexOf(haystack, needle) {
return haystack.map(JSON.stringify).indexOf(JSON.stringify(needle));
}
var arr = [[1], [2], [3]];
serialisedIndexOf(
arr,
[2]
); // 1
// so the original reference for [2] can be obtained at arr[1]
,它总是会至少经过一次数组中的每一项),但需要更多的代码来实现
.map
在 ES6 中,我们将Array.prototype.findIndex
可以为我们提供function serialisedIndexOf(haystack, needle) {
var i, r;
needle = JSON.stringify(needle);
r = haystack.some(function (e, idx) {
i = idx;
return JSON.stringify(e) === needle;
});
return r ? i : -1;
}
方法的较短版本,但您不应该假设浏览器支持
.some