通过角度移动DOM元素时保持焦点

时间:2019-06-07 14:12:03

标签: javascript angular typescript

我使用*ngFor渲染一个动作表。这些操作按优先级排序,但是当用户通过与表中的<input type="number">进行交互来编辑操作详细信息时,优先级可能会更改。我希望排序顺序在更改后立即更新。

问题在于,通过临时将表行从DOM中删除,角度移动表行将导致其中的<input>在用户键入时失去焦点。有什么方法可以防止这种情况吗?

我尝试过的事情

我通过指定trackBy启用了DOM元素重用:

<tr *ngFor="let a of actions; trackBy: sameName">
  <td>{{a.roi}}</td>
  <td>{{a.name}}</td>
  <td><input type="number" [(ngModel)]="a.stateInfo" (ngModelChange)="updateActions()"></td>
</tr>

并能够在开发人员工具中确认DOM节点实际上已被重用。

但是在元素删除上设置DOM断点仍然会产生以下堆栈跟踪:

removeChild (platform-browser.js:1921)
removeChild (core.js:36584)
execRenderNodeAction (core.js:22849)
visitRenderNode (core.js:22815)
visitSiblingRenderNodes (core.js:22737)
visitRootRenderNodes (core.js:22720)
renderDetachView$1 (core.js:23404)
moveEmbeddedView (core.js:23375)
move (core.js:23716)
(anonymous) (common.js:4516)
forEachOperation (core.js:20644)
_applyChanges (common.js:4496)
ngDoCheck (common.js:4485)
checkAndUpdateDirectiveInline (core.js:24492)

确认ViewContainer通过将子视图暂时从DOM中移除来移动子视图,我怀疑这会导致焦点丢失。

2 个答案:

答案 0 :(得分:1)

您可以尝试将其添加到输入中:

[attr.id]="'action-input-' + a.roi"

并更新这样的updateAction:

updateActions = (roi) => {

    // Sorting..

    // Find input
    const input = document.getElementById(`action-input-${roi}`);

    // Add to the end of the queue
    setTimeout(() => {
        input.focus()
    });
}

不要忘记将参数传递给updateActions:

(ngModelChange)="updateActions(a.roi)"

答案 1 :(得分:1)

找不到更好的方法,我选择放宽要求并推迟更新表,直到用户希望完成键入为止:

在模板中:

server {
  listen       80;
  server_name ~^(?<subdomain>.*?)\.;
  resolver kube-dns.kube-system.svc.cluster.local valid=5s;

  location / {
      proxy_pass         http://$subdomain.my-internal-host.default.svc.cluster.local;
      root   /usr/share/nginx/html;
      index  index.html index.htm;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
      root   /usr/share/nginx/html;
  }
}

并在组件中:

(ngModelChange)="updateRequest.emit()"

更好的主意仍然受到欢迎!

相关问题