如果事件不是来自ng-repeat中的元素(即不是ng-click),如何从ng-repeat获取值

时间:2015-06-16 07:05:48

标签: javascript angularjs angularjs-directive angularjs-ng-repeat angular-filters

我有一个用于类别标记的超前模糊搜索指令:

<input type="text" class="form-control" placeholder="Apply Tags" ng-keydown="checkKeyDown($event)" ng-change="searchTags()" ng-model="searchText">
<div ng-show="searchText.length>0">
    <ul>
        <li ng-repeat="tag in suggestedTags | fuzzySearch : searchText : 'OR' track by $index" ng-class="{active : $index === selectedIndex}">
            {{tag}}
        </li>
    </ul>
</div>

这就是我处理事情的方式

suggestedTags: array of strings that is the full list of tags I want to match
selectedIndex: the index of the filtered suggestedTags, based on searchText
searchText: the string I'm using to match up with suggestedTags

当我输入内容时,模糊搜索会检查我输入的内容是否与数组匹配,并缩短建议结果列表。 这样可以正常使用

但是,我有以下代码,允许我使用键盘从过滤列表中选择(使用向上,向下和输入键):

scope.checkKeyDown = function(event) {
  if (event.keyCode === 40) { //down key, increment selectedIndex
    event.preventDefault();
    if(scope.selectedIndex+1 !== scope.suggestedTags.length){ // check to see if at end of list
      scope.selectedIndex++;
    }
  } else if (event.keyCode === 38) { //up key, decrement selectedIndex
    event.preventDefault();
    if(scope.selectedIndex-1 !== -1){ // check to see if at top of list
      scope.selectedIndex--;
    }
  } else if (event.keyCode === 13) { //enter pressed
    event.preventDefault();
    scope.addToSelectedTags(scope.selectedIndex); //adds to selected tags
  }
}
scope.addToSelectedTags = function (index) {
  if(scope.selectedTags.indexOf(scope.suggestedTags[index]) > -1) return; // Test to see if selectedTags already has this value
    scope.selectedTags.push(scope.suggestedTags[index]);
};

这里的问题是selectedIndex将是过滤列表中的索引,但是当我推送到selectedTags时,它将来自完整的suggestedTags数组。

最简单的方法是从所选的任何内容中传入字符串值。我怎样才能做到这一点?有没有办法将ng-model放在<li>(重复)上,让它选择什么是活动的?

1 个答案:

答案 0 :(得分:1)

&#13;
&#13;
function Ctrl($scope, $filter) {
  var suggestedTags = ['javascript', 'angular', 'android', 'java', 'c++', 'c#', 'object-c']
  $scope.selectedIndex = 0;
  $scope.filteredTags = suggestedTags;
  $scope.selectedTags = [];
  $scope.checkKeyDown = function(event) {
    if (event.keyCode === 40) { //down key, increment selectedIndex
      console.log('down');
      event.preventDefault();
      if ($scope.selectedIndex + 1 !== $scope.filteredTags.length) { // check to see if at end of list
        $scope.selectedIndex++;
      }
    } else if (event.keyCode === 38) { //up key, decrement selectedIndex
      console.log('up')
      event.preventDefault();
      if ($scope.selectedIndex - 1 !== -1) { // check to see if at top of list
        $scope.selectedIndex--;
      }
    } else if (event.keyCode === 13) { //enter pressed
      event.preventDefault();

      $scope.addToSelectedTags($scope.selectedIndex); //adds to selected tags
      console.log('enter');
    }
  }

  $scope.searchTags = function() {
    $scope.selectedIndex = 0;
    $scope.filteredTags = $filter('filter')(suggestedTags, $scope.q);
  }

  $scope.addToSelectedTags = function(index) {
    if ($scope.filteredTags.length - 1 >= index) {
      var selectedTag = $scope.filteredTags[index];
      //angular doesnt like duplicate in ng-repeat
      //if you want to have duplicate tag name, you can use track by 
      //or create new object so angular doesnt see it as duplicated

      if ($scope.selectedTags.indexOf(selectedTag) < 0)
        $scope.selectedTags.push(selectedTag);
    }

  }
}
&#13;
.active {
  background-color: red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<div ng-app ng-controller="Ctrl">
  <input tpye="text" ng-model="q" ng-keydown="checkKeyDown($event)" ng-change="searchTags()" />
  <ul>
    <li ng-repeat="tag in filteredTags" ng-class="{active : $index === selectedIndex}">{{tag}}</li>
  </ul>

  <ul>
    <li ng-repeat="t in selectedTags">{{t}}</li>
  </ul>
</div>
&#13;
&#13;
&#13;