javascript - Angular 模型变量在 DOM 更新之前更新过早,导致 UI 为 "behind"?

标签 javascript jquery angularjs dom angularjs-digest

我正在尝试构建一个 Angular 标签指令,其功能与 Stack Overflow 的标签输入表单不太相似。它使用带有边框的 div 来创建表单的效果,然后在输入字段左侧使用包含标签列表的 div,您可以在其中键入:

<div class="wrapper">
    <div class="tag-wrapper">
        <div class="tags" ng-repeat="tag in selectedTags">
            <div>
                [[ tag.name ]]
                <span class="remove" ng-click="removeTag(tag)"></span>
            </div>
        </div>
    </div>
    <input type="text" class="tag-input"
           ng-model="tagInput"
           ng-style="{ width: inputLength + 'px'}"
           ng-keypress="tagInputKeyPress($event)"
           ng-keyup="updateSuggestionList()"
           ng-focus="toggleSuggestionVisibility()"
           ng-blur="toggleSuggestionVisibility()" />
</div>

请注意,我使用 [[]] 作为 Angular 的插值提供程序,因为我有另一个模板引擎已经在使用 {{}}

当在输入中按下某个键时,它会运行一个函数来检查该键是否是退格键、回车键或空格来创建/删除标签:

$scope.tagInputKeyPress = function(event) {
    // Currently using jQuery.event.which to detect keypresses, keyCode is deprecated, use KeyboardEvent.key eventually:
    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

    // event.key == ' ' || event.key == 'Enter'
    if (event.which == 32 || event.which == 13) {
        event.preventDefault();

        // Remove any rulebreaking chars
        var tag = $scope.tagInput;
        tag = tag.replace(/["']/g, "");
        // Remove whitespace if present
        tag = tag.trim();

        $scope.createTag(tag);

    // event.key == 'Backspace'
    } else if (event.which == 8 && $scope.tagInput == "") {
        event.preventDefault();

        // grab the last tag to be inserted (if any) and put it back in the input
        if ($scope.selectedTags.length > 0) {
            $scope.tagInput = $scope.selectedTags.pop().name;
        }
    }
    $scope.inputLength = $(element).find('input.tag-input').parent().innerWidth() - $(element).find('.tag-wrapper').outerWidth() - 1;

    return true;
};

我遇到问题的是 return 语句之前的最后一行。 它的目的是重新计算 .tag-wrapper 元素的宽度,并通过此调整 input 元素的宽度以适应ng-style 属性:

ng-style="{ width: inputLength + 'px'}"

但是,就目前情况而言,输入长度始终落后 UI 一步,导致输入溢出。这是因为:

  1. 它首先将一个新标签添加到 selectedTags 列表中。
  2. 它计算 .tag-wrapper 的宽度。
  3. 返回 true 让原始按键事件通过
  4. Angular 的摘要循环运行并将新标签附加到 DOM 中。 .tag-wrapper 的宽度现在更大,input 会溢出。

这是一个例子:

enter image description here

现在,步骤 4 在步骤 2 之后进行。我需要在步骤 4 之后进行步骤 2

我怎样才能实现这个目标?

最佳答案

您修改 createTag 方法以进行回调,并在回调中设置 inputLength。

替代黑客:将 inputLength 的设置包装在 $timeout 内,以强制在以下摘要调用中执行该行。

关于javascript - Angular 模型变量在 DOM 更新之前更新过早,导致 UI 为 "behind"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32291608/

相关文章:

javascript - 有两个弹出窗口。不应同时显示两个弹出窗口。一次只能显示一个弹出窗口。这可能吗?

javascript - 使用 boolean 值作为参数的高阶函数

jquery - 在调用 toggle() 之前 Div 淡出

javascript - 当没有使用 angular-file-upload 指令上传文件时?

javascript - AngularJs:两个嵌套的子状态但不同的 View

javascript - AngularJS 如何在服务和 Controller 之间设置双向数据绑定(bind)

javascript - FFmpeg:同时使用 xfade 和 crossfade 时音频不同步

javascript - 单击按钮后加载图像

javascript - 向数据表中的项目添加 "data"选项

javascript - 如何使用 $(target) inside 指令?