2015-04-12 78 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; 
    }); 
}