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

access md-autocomplete input value before model debouce evaluation in AngularJs

我有一个场景,我想使用 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 中实现一个搜索页面,其中包含 'best bet' 建议以及显示全文搜索结果。

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

I am using Azure Search API to serve the Query and Suggestions, the implementation of this is out of scope for the question, but a quick plug, it produces super fast responses over large indexes, faster than any SQL I can try to write...

我已经使用 debounce 模型选项来延迟对服务的建议查询,这工作得很好,但是由于使用了 debounce,我无法访问通过绑定输入,直到去抖周期结束。

<!-- 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 用来延迟建议请求的值,同时允许搜索按钮用来立即访问原始值的全文搜索查询

In researching a good way to describe my issue, and add references to my question I found 2 solutions

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

    md-delay
    [number]: Specifies the amount of time (in milliseconds) to wait before looking for results

    所以我们现在可以删除 model-options debounce 语句并改用 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];