2

所以在这里我试图用角度实现自动完成建议,我需要你的专业知识。

这是html:

<div my-autosuggest>
    <input type="text" my-autosuggest-input>
    <ol>
         <li ng-repeat"item in items" my-autosuggest-list>...</li>
    </ol>
</div>

我不想使用模板来生成<li>元素。(我希望它可以灵活地以任何顺序使用任何类型的元素,并且可能在列表和下拉列表之间使用其他一些额外的元素)

困难的部分是响应输入上的箭头键以突出显示列表中的下一个/上一个元素。如何让另一个指令my-autosuggest-list知道它应该从my-autosuggest-input指令中选择下一个元素。

请注意,我可能在一个控制器中有多个自动建议,如下所示:

<div ng-controller="MyController">
   <div my-autosuggest>
       <input type="text" my-autosuggest-input>
       <ol>
            <li ng-repeat"item in items" my-autosuggest-list>...</li>
       </ol>
   </div>
   <div my-autosuggest>
       <ol>
            <li ng-repeat"item in items" my-autosuggest-list>...</li>
       </ol>
       <input type="text" my-autosuggest-input>
   </div>
</div>

到目前为止,我已尝试$watch更改索引,但有时不会为列表中的某些元素调用手表(也许这是一个错误)。$broadcast 不起作用,因为输入可能被包装在另一个控制器或另一个元素中,因此列表不会听到广播。

我还尝试在根范围内为每个自动建议放置一个变量,但指令的调用顺序并不总是从父级到子级,因此我无法初始化该变量并每次my-autosuggest调用创建一个新变量,因为my-autosuggest-input或其他可能是在那之前打电话。

任何关于如何用角度设计这个的建议都值得赞赏。

4

1 回答 1

2

假设my-autosuggest-inputandmy-autosuggest-list总是在一个my-autosuggest. 您可以使用一系列$emitted$broadcast事件来完成此操作。

当按下箭头键时,在的my-autosuggest-input链接函数中添加一个:$emit

element.on('keyup', function () {
   // Figure out if this is an arrow key, if so:
   $scope.$emit('listSelect', { message: 'prevItem' }); // Or 'nextItem'
});

my-autosuggest链接函数或控制器内添加:

// Add a controllerId, so that the listener doesn't handle its own events.
$scope.controllerId = Math.random().toString();
$scope.$on('listSelect', function (e, data) {
    if ($scope.controllerId !== data.controllerId) {
        $scope.$broadcast('listSelect', { 
            controllerId: $scope.controllerId,
            message: data.message 
        });
    }
});

最后,在里面my-autosuggest-list的链接函数或者控制器中添加:

$scope.$on('listSelect', function (e, data) {
    if (data.message === 'nextItem') {
        // Highlight next item.
    } else {
        // Highlight previous item.
    }
});

在这种情况下,将my-autosuggest任何事件从它的任何孩子路由listSelect到它的所有孩子。

于 2013-05-02T15:37:05.353 回答