在 AngularJs 中的模型去布斯评估之前访问 md-autocomplete 输入值



我有一个场景,我想使用 ng-model-options 来去反弹输入值,但我有一个特定的用例,我需要在去抖动周期之前访问原始输入值。

特殊情况,当用户点击回车键或按下搜索按钮时,我想立即访问输入的值,即使去抖动期尚未过期。事实证明,在生产中键入搜索查询的用户通常会很快按回车键,谁知道呢?

因此,由于模型还没有我需要的值,因此我尝试直接访问html输入值jQuery:

var searchBox = document.getElementById('searchBox');
var el = angular.element(searchBox);
var val = el.val();

同样在原始的javascript中:

var searchBox = document.getElementById('searchBox');
var val = searchBo.value;

但是这些结果给了我一个空值。

更复杂的是,我正在使用 md-autocomplete,它具有自己的内置功能,我宁愿不复制或尝试修改太多,并且我不确定如何直接针对指令的输入字段以获取 .val()

背景:

我正在尝试在 AngularJs 中实现一个具有"最佳匹配">建议并显示全文搜索结果的搜索页面。

自动完成功能将在用户键入时调用服务以获取建议,但这些建议将与数据模型中的特定字段完全匹配。 将进行完整的测试搜索

我正在使用 Azure 搜索 API 来提供查询和建议,这超出了问题的范围,但是一个快速插件,它对大型索引产生超快的响应,比我可以尝试编写的任何 SQL 都快......

我使用了去抖动模型选项来延迟对服务的建议查询,这运行良好,但由于使用了去抖动,在抖动期到期之前,我无法通过绑定访问输入的值。

<!-- The Search Box -->
<form ng-submit="$event.preventDefault()">
<div layout="row">
<md-autocomplete id="searchBox"
ng-disabled="false"
md-no-cache="true"
md-search-text="vm.searchText"
ng-model-options="{ debounce: 300 }"
md-selected-item-change="vm.selectedItemChange(item)"
md-items="item in vm.querySuggester(vm.searchText)"
md-item-text="item.Text"
md-min-length="1"
placeholder="Search articles..." layout-fill>
<md-item-template>
<span md-highlight-text="vm.searchText" md-highlight-flags="i">{{item.Text}}</span>
</md-item-template>
</md-autocomplete>
<button type="submit" ng-click="vm.querySearch(vm.searchText)">
Search
</button>
</div>
</form>
...
<!-- Search Results -->
<md-list class="browser-list">
<md-list-item ng-repeat="selected in vm.SearchResponse.Results"
ng-click="vm.selectItem(selected)">
<catalogue-Summary ng-if="selected.Document.Catalogue" data="selected.Document" highlights="selected.Highlights" score="selected.Score" entity-name="'dataEntries'" show-in-list="true" class="full-width"></catalogue-Summary>
<article-Summary ng-if="!selected.Document.Catalogue" data="selected.Document" highlights="selected.Highlights" score="selected.Score" entity-name="'contentEntries'" show-in-list="true" class="full-width"></article-Summary>
<md-divider ng-if="!$last"></md-divider>
</md-list-item>
</md-list>

所以我想去反弹 md-autocomplete 用于延迟建议请求的值,同时允许搜索按钮用于立即访问原始值的全文搜索查询

在研究一种描述我的问题并添加对我问题的引用的好方法时,我找到了 2 个解决方案

  1. md-autocomplete 文档列出了为此类方案显式设计的 md-delay 属性,您希望模型立即绑定,但希望延迟搜索函数的调用

    MD-延迟
    [数字]: 指定在查找结果之前等待的时间量(以毫秒为单位)

    因此,我们现在可以删除模型选项去抖动语句,改用 MD-delay:

    <md-autocomplete id="searchBox"
    ng-disabled="false"
    md-no-cache="true"
    md-search-text="vm.searchText"
    md-delay="300"
    md-selected-item-change="vm.selectedItemChange(item)"
    md-items="item in vm.querySuggester(vm.searchText)"
    md-item-text="item.Text"
    md-min-length="1"
    placeholder="Search articles..." layout-fill>
    <md-item-template>
    <span md-highlight-text="vm.searchText" md-highlight-flags="i">{{item.Text}}</span>
    </md-item-template>
    </md-autocomplete> 
    
  2. 您还可以通过访问 html 元素的第二个后代直接引用上述输入字段的输入值,这是因为上面的代码片段将在运行时呈现为以下结构:(我已经从原始输出中删除了大多数属性来解释这一点)

    <md-autocomplete>
    <md-autocomplete-wrap>
    <!-- ngIf: !floatingLabel -->
    <input name="" ng-model="$mdAutocompleteCtrl.scope.searchText"></input>
    <!-- end ngIf: !floatingLabel -->
    <!-- ngIf: $mdAutocompleteCtrl.scope.searchText && !$mdAutocompleteCtrl.isDisabled -->
    <!-- ngIf: $mdAutocompleteCtrl.loadingIsVisible() -->
    </md-autocomplete-wrap>
    <aria-status class="md-visually-hidden" role="status" aria-live="assertive"></aria-status>
    </md-autocomplete>
    

    我们希望直接访问输入字段 因此,以下脚本将允许您访问该值,即使去抖动意味着模型还没有该值:

    var searchInput = document.getElementById('searchBox').firstElementChild.firstElementChild;
    var value = searchInput.value;
    

    如果不知道 md-autocomplete 如何呈现的完整结构,但知道最终我们需要内部输入控件,那么以下内容将是更有用的第一次尝试:

    var searchInput = document.getElementById('searchBox').getElementsByTagName('input')[0];
    

最新更新