2015-04-12 46 views
0

我有一个数组在输入框中输入时被过滤/搜索。当我点击返回时,输入文本被追加到数组中。这是伟大的,它的工作原理。indexOf()== -1在推入数组时似乎不起作用

什么不工作是$ 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,指令&控制器

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

在该示例中,“if”语句将检查数组中是否存在键入的内容。如果它不存在,那么-1是真的,推动会发生。或者我错过了明显的东西? – ssedwards

+0

这是一个经典的例子{}!== {}' –

回答

1

由于$scope.listObject的列表,因此测试$scope.list.indexOf(elem)适用于总是不同的2 Object的参考文献。

你可以使用$filter('filter')(array, expression, comparator)AngularJS

$scope.addItem = function() { 
    var elem = {name: $scope.addName}; 
    if ($filter('filter')($scope.list, {name: elem.name}).length == 0) { 
     $scope.list.push(
      elem 
     ); 
    }  
}; 
+0

我喜欢这个答案的简单性。这对我来说很有效,没有我需要考虑的问题。感谢大家的评论,我很欣赏快速反应。 – ssedwards

0

远离电脑,所以我采取了刺,但它好像你正试图执行字符串运算在一个对象上(项目列表)。

1

JavaScript不考虑的对象是相同的,因为它们不是同一个实例。很好地解释了This link

我建议使用下划线的findWhere来测试是否存在具有相同属性的对象。

你的情况:

if (_.findWhere($scope.list, elem) === undefined){ 
    $scope.list.push(elem); 
} 

你会的,当然,需要包括下划线来使用它。由于您使用的角度,你可能要使用这样的:

https://github.com/floydsoft/angular-underscore

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

试试这个,我不能够马上进行测试,但我想它的解决问题的办法。

0

您当前indexOf是失败的,因为没有两个对象是相同的,除非他们是相同的,即{} !== {}var o = {}; o === o;

当你试图找到一个参考,知道如何对象最初创建和你对象可以序列化为JSON没有出现任何的错误,你可以使用最后一点,为执行indexOf代替

例如,利用Array.prototype.map

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] 

你同样可以使用Array.prototype.some能在第一场比赛(VS的.map以上,这将始终贯穿每一个项目去数组至少一次)结束,但需要更多一点的代码来实现

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

ES6我们会有Array.prototype.findIndex这可以给我们.some方法的较短的版本,但你不应该承担这个浏览器的支持又

function serialisedIndexOf(haystack, needle) { 
    needle = JSON.stringify(needle); 
    return haystack.findIndex(function (e) { 
     return JSON.stringify(e) === needle; 
    }); 
}