在使用 typeahead 的时候,有这样一个需求,当用户选中其中一项的以后,将项目对应的 id 保存到另一个变量中,之后在提交表单的时候,将这个 id 发送到服务器中。java
可是,在 typeahead 中对于元素的操做,angularjs 没有感知到,致使不能获取最新的数据。angularjs
在 typeahead 中,咱们能够定义一个 itemSelected 的事件处理函数,在选中一个项目以后, typeahead 会触发这个事件,咱们在这个事件中能够获取当前选中的元素,对应的值,已经显示的提示文本。ajax
这个函数的使用方式以下:服务器
itemSelected: function (item, val, text) { console.info(val); }
集成到页面中,咱们能够以下配置 typeahead 的配置参数。app
var option = { ajax: { url: '@Url.Action("AjaxService")', timeout: 300, method: "post", triggerLength: 3, preDispatch: function (query) { return { type: type, query: query }; }, preProcess: function (data) { return data; } }, display: "name", val: "id", itemSelected: function (item, val, text) { console.info(item); } }; $("#tbxName").typeahead(option);
可是,在使用 angularjs 的时候,会带来一个问题,若是咱们直接将这个 id 赋予某个元素,好比说输入框的话,angularjs 是不能检测到这个元素值的变化的,angularjs 经过监测元素的获取焦点,失去焦点,change 等事件来感知输入元素的变化,在经过代码直接赋值的时候,会没有这些事件的触发。函数
咱们能够经过 angularjs 的自定义指令将 typeahead 封装一下,在 itemSelected 事件触发的时候,调用 angularjs 的 $apply 发出通知,这样 angularjs 天然就能够感知到数据的变化了。post
为了便于已经熟悉 typeahead 的朋友,继续使用原来的方式进行配置,咱们不修改配置方式。ui
指令的定义以下:url
// 自定义指令 app.directive("typeahead", function () { var option = { restrict: "A", require: "?ngModel", scope: { option: "=typeahead" }, link: function (scope, element, attrs, ngModel) { // typeahead 的配置参数 var option = scope.option; // 将原来的 itemSelected 替换为 angularjs 的 itemSelected 函数 // 在用户选择了选项以后,经过 angularjs 执行 var itemSelected = option.itemSelected; option.itemSelected = function (item, val, text) { scope.$apply(function () { itemSelected(item, val, text); }) }; element.typeahead(option); } }; return option; });
scope 是自定义一个做用域,=typeahead 是将 typeahead 属性的值取过来,剩下的处理就比较简单了,咱们将原来的 itemSelected 事件截获过来,经过 scope.$apply 进行处理,这样 angularjs 天然就能够获取数据的变化了。spa
元素的定义以下,增长一个名为 typeahead 的 Attribute, 值就是配置参数对象,定义在 angularjs 的模型对象上。
<input typeahead ="typeaheadOption" ng-model="petName" type="text" />
下面是对应的脚本。
// 控制器 app.controller("myController", function ($scope) { // 额外附加的参数 $scope.type = "java"; // 标准的使用方式 $scope.petName = "Cat"; $scope.petId = ""; // 使用标准的 typeahead 配置参数, 在元素上使用 typeahead Attribute 链接 $scope.typeaheadOption = { ajax: { url: '@Url.Action("AjaxService")', timeout: 300, method: "post", triggerLength: 3, preDispatch: function (query) { return { type: $scope.type, query: query }; }, preProcess: function (data) { return data; } }, display: "name", val: "id", itemSelected: function (item, val, text) { $scope.petId = val; } }; });
使用 angularjs 的自定义指令,咱们能够很容易地将 angularjs 以外的事件处理封装到 angularjs 之中。