需要帮助创建执行TypeAhead功能的指令

时间:2014-03-16 23:01:58

标签: javascript jquery angularjs

背景

如果您有任何人熟悉Evernote桌面应用程序,则在向笔记添加标签时,您可以开始键入标签的名称。一旦开始输入,"帮助文本"似乎可以帮助您选择正确的标签。所以它起到过滤器的作用。对于我的Web应用程序,我需要一个像这样的控件。

我到目前为止

在我的controllers.js文件中,我为临时测试定义了以下属性。一旦我使用测试数据,就会使用API​​中的数据填充此属性。

$scope.data.types = {Types: [{name: 'Developer'}, {name: "\"Developer Company\""}, {name: 'Accountant'}, {name: "\"Legal Counsel\""}]};

在我的路线模板文件contacts-edit.html中,我有以下相关代码。基本上,我有一个可编辑的<div>,可以从$scope.data.contacts中提取并显示持久性标记(即为数据库中的此联系人保存的标记)。

<div class="form-group">
    <label for="entity_types" class="control-label col-sm-2">Tags</label>
    <div class="col-sm-5">
        <div class="form-control" contenteditable="true" ng-model="data.contact.EntityTypes" my-Directive my-Other-Directive></div>
    </div>
</div>

我的directives.js文件中包含myDirectivemyOtherDirective的代码。 myDirective指令使用ngModel来提供双向数据绑定。因此,当用户键入div时,在blur上,标签会添加到模型中,并且格式化为与标签类似。这些标记以空格分隔,并允许忽略双引号之间的标记空格。所以myDirective以我想要的方式运作。

但是,我对如何提供我希望通过myOtherDirective指令提供的过滤功能感到有点困惑。我可能认为这一切都是错的,所以任何帮助都是有益的。

myOtherDirective指令

所以这里的想法是,一旦最终用户开始输入,<span>会直接显示在<div>下方,显示使用scope.data.types.Types数据作为模型的过滤结果要过滤的数据。结果不需要是可点击的或任何东西,它们只是帮助最终用户输入正确的联系人标签。

代码

directives.directive('myOtherDirective', [function() {

    var template = "<span class='help-block'>" +
        "<ul class='list-unstyled list-inline'>" +
        "<li ng-repeat='type in data.types.Types'><small>{{type.name}}</small></li>" +
        "</ul></span>";

    function link(scope, element, attrs) {
        element.on('focus', function(e) {
            scope.$apply(function() {
                element.parent().append(template);
            });
        });
    }

    return {
        restrict: 'A',
        link: link,
        scope: {
            type: '='
        },
        template: template
    };
}]);

因此,我可以在<div>获得焦点后立即显示帮助屏幕(顺便提一下blur删除它)。我无法使数据绑定在data.types.Types上运行,并且不知道下一步该怎么做。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

如果您尝试为输入框设置自动完成功能,我会使用ui-bootstrap's typeahead

答案 1 :(得分:0)

type参数传递给指令时会导致它具有隔离范围。这意味着您将无法在指令中访问$scope.data表单。要解决此问题,您也可以传递data

scope: {
    type: '='
    data: '='
}