使用AngularJS创建一个Typeahead小部件

如果您正在启动AngularJS项目,则可能需要用Angular编写所有组件。 尽管当然可以重用现有的jQuery插件,但是在指令中抛出一堆jQuery并非总是正确的方法。 我的建议是首先检查是否可以用更简单/更好的方式使用纯Angular实现相同的功能。 这样可以使您的应用程序代码保持干净和可维护。 本教程面向初学者,引导读者完成使用AngularJS创建简单的TypeAhead小部件的过程。

总览

在本教程中,我们将构建一个简单的TypeAhead小部件,一旦有人开始在文本框中键入内容,它就会创建建议。 我们将以这种方式设计该应用程序,使最终产品具有很高的可配置性,并且可以轻松地将其插入到现有系统中。 创建过程涉及的基本步骤是:

  • 创建一个与RESTful API进行交互的工厂,并返回将用于自动完成建议的JSON。
  • 创建将使用JSON数据的指令,并封装预输入字段。
  • 保持该指令可配置,以便最终用户可以配置以下选项。

配置选项

  1. 作为建议一部分显示的确切JSON对象属性。
  2. 控制器范围内的模型,将保存选定的项目。
  3. 选中项目时执行的控制器范围内的功能。
  4. 提前输入字段的占位符文本(提示)。

步骤1:建立工厂以获取数据

第一步,我们创建一个工厂,该工厂使用Angular的$http服务与RESTful API进行交互。 请看以下片段:

var typeAhead = angular.module('app', []);

typeAhead.factory('dataFactory', function($http) {
  return {
    get: function(url) {
      return $http.get(url).then(function(resp) {
        return resp.data; // success callback returns this
      });
    }
  };
});

之前的代码创建了一个名为dataFactory的工厂,该工厂从API检索JSON数据。 我们不会详细介绍工厂,但是我们需要简要了解$http服务的工作方式。 您将URL传递给get()函数,该函数返回一个Promise。 在此promise上对then()另一个调用也返回了另一个promise(我们从工厂的get()函数返回此promise)。 通过传递给then()的成功回调的返回值来解决此承诺。 因此,在我们的控制器内部,我们不直接与$http交互。 相反,我们在控制器中请求factory的实例,并使用URL调用其get()函数。 因此,与工厂交互的控制器代码如下所示:

typeAhead.controller('TypeAheadController', function($scope, dataFactory) { // DI in action
  dataFactory.get('states.json').then(function(data) {
    $scope.items = data;
  });
  $scope.name = ''; // This will hold the selected item
  $scope.onItemSelected = function() { // this gets executed when an item is selected
    console.log('selected=' + $scope.name);
  };
});

前面的代码使用一个名为states.json的API端点,该端点返回美国各州的JSON列表。 当数据可用时,我们将列表存储在范围模型items 。 我们还使用模型name来保存所选项目。 最后,当用户选择特定状态时,函数onItemSelected()被执行。

步骤2:建立指令

让我们从如下所示的typeahead指令开始。

typeAhead.directive('typeahead', function($timeout) {
  return {
    restrict: 'AEC',
    scope: {
      items: '=',
      prompt: '@',
      title: '@',
      subtitle: '@',
      model: '=',
      onSelect: '&'
    },
    link: function(scope, elem, attrs) {
    },
    templateUrl: 'templates/templateurl.html'
  };
});

在指令中,我们正在创建一个隔离的范围,该范围定义了几个属性:

  • items :用于将JSON列表传递到隔离的范围。
  • prompt :一种方式传递的占位符文本的结合typeahead输入字段。
  • titlesubtitle :自动完成字段的每个条目都有一个titlesubtitle 。 大多数typeAhead小部件都以这种方式工作。 在下拉建议中,每个条目通常(如果不是总是)有两个字段。 如果JSON对象具有其他属性,则这是传递两个属性的一种方式,这两个属性将显示在下拉菜单的每个建议中。 在我们的例子中, title对应于州名,而subtitle表示其缩写。
  • model :两种方式绑定以存储选择。
  • onSelect :方法绑定,一旦选择结束,用于在控制器范围内执行功能。

注意: JSON响应示例如下所示:

{
  "name": "Alabama",
  "abbreviation": "AL"
}

步骤3:建立范本

现在,让我们创建一个将由指令使用的模板。

<input type="text" ng-model="model" placeholder="{{prompt}}" ng-keydown="selected=false" />
<br/>

<div class="items" ng-hide="!model.length || selected">
  <div class="item" ng-repeat="item in items | filter:model  track by $index" ng-click="handleSelection(item[title])" style="cursor:pointer" ng-class="{active:isCurrent($index)}" ng-mouseenter="setCurrent($index)">
    <p class="title">{{item[title]}}</p>
    <p class="subtitle">{{item[subtitle]}}</p>
  </div>
</div>

首先,我们呈现一个输入文本字段,供用户输入。 范围属性prompt被分配给placeholder属性。 接下来,我们遍历状态列表并显示nameabbreviation属性。 这些属性名称是通过titlesubtitle范围属性配置的。 当用户将鼠标悬停时,指令ng-mouseenterng-class用于突出显示该条目。 接下来,我们使用filter:model ,它通过在输入字段中输入的文本来过滤列表。 最后,当输入文本字段为空或用户选择了一个项目时,我们使用ng-hide指令隐藏了列表。 在handleSelection()函数中, selected属性设置为true ,当有人开始在输入字段中键入内容时,将其设置为false false (以显示建议列表)。

步骤4:更新link功能

接下来,让我们更新指令的link功能,如下所示。

link: function(scope, elem, attrs) {
  scope.handleSelection = function(selectedItem) {
    scope.model = selectedItem;
    scope.current = 0;
    scope.selected = true;
    $timeout(function() {
      scope.onSelect();
    }, 200);
  };
  scope.current = 0;
  scope.selected = true; // hides the list initially
  scope.isCurrent = function(index) {
    return scope.current == index;
  };
  scope.setCurrent = function(index) {
    scope.current = index;
  };
}

函数handleSelection()使用选定的状态名称更新范围属性model 。 然后,我们重置currentselected属性。 接下来,我们调用函数onSelect() 。 由于分配scope.model=selecteditem不会立即更新绑定的控制器作用域属性,因此添加了延迟。 在使用所选项目更新模型之后,希望执行控制器作用域回调函数。 这就是我们使用$timeout服务的原因。

此外,函数isCurrent()setCurrent()在模板中一起使用,以突出显示自动完成建议中的条目。 以下CSS也用于完成突出显示过程。

.active {
  background-color: #C44741;
  color: #f2f2f2;
}

步骤5:配置和使用指令

最后,让我们在HTML中调用指令,如下所示。

<div class="container" ng-controller="TypeAheadController">
  <h1>TypeAhead Using AngularJS</h1>
  <typeahead items="items" prompt="Start typing a US state" title="name" subtitle="abbreviation" model="name" on-select="onItemSelected()" />
</div>

结论

本教程向您展示了如何使用配置选项创建AngularJS TypeAhead小部件。 完整的源代码可在GitHub上下载。 如果有不清楚的地方或您想改善任何地方,请随时发表评论。 另外,不要忘记查看现场演示

From: https://www.sitepoint.com/creating-a-typeahead-widget-with-angularjs/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值