IE11/Edge 中 aurelia bindingsignaler 的延迟动作

Delayed action of aurelia bindingsignaler in IE11/Edge

简短版:请看一下这个plunkr:http://plnkr.co/edit/ZdiXFOS3huYhqT3CC7i1?p=preview

我有一个网格,其中包含一些数值输入字段。如果我更改其中一个输入中的可编辑值,则应更新行总计。这在 Chrome 中工作正常(= 正如我所期望的那样),但在 IE11 / Edge 中不行。在 Microsoft 浏览器中,总数将在下一个 "blur" 事件中更新,这不是我需要的行为。

更长的描述: 我的网格 (app.html)(在现实生活中这将是对话框中的一个表单)

<template>

  <require from="my-input"></require>
  <require from="my-format"></require>

  <table class="table">
    <thead>
      <tr>
        <td>&nbsp;</td>
        <td>North</td>
        <td>East</td>
        <td>West</td>
        <td>South</td>
        <td>Total</td>
      </tr>
    </thead>
    <tbody>
      <tr repeat.for="r of data.rows">
        <td>${r.year}</td>
        <td><my-input val.two-way="r.v1"></my-input></td>
        <td><my-input val.two-way="r.v2"></my-input></td>
        <td><my-input val.two-way="r.v3"></my-input></td>
        <td><my-input val.two-way="r.v4"></my-input></td>
        <td>${sumRow(r.year) & signal:'mySignal'}</td>
      </tr>
    </tbody>
  </table>

</template>

app.js:

import 'bootstrap';
import 'bootstrap/css/bootstrap.css!';

export class App {
  data = {
    "rows": [{
      "year": "2014",
      "v1": 100,
      "v2": 200,
      "v3": 300,
      "v4": 400
    }, {
      "year": "2015",
      "v1": 500,
      "v2": 600,
      "v3": 700,
      "v4": 800
    }, {
      "year": "2016",
      "v1": 900,
      "v2": 1000,
      "v3": 1100,
      "v4": 1200
    }]
  }

sumRow(y) {
        var row = this.data.rows.find((item) => item.year === y);
        return row.v1 + row.v2 + row.v3 + row.v4;
    }
}

我正在使用自定义输入元素,因为所有值都需要格式化为德语数字格式,这需要在模糊时更新输入。

我的-input.html

<template>
    <require from="./my-format"></require>

    <input type="text" value.bind="val | myFormat & updateTrigger:'blur':'paste'" class="form-control" blur.trigger="myOnBlur()" />

</template>

要在更改值后触发行总数的计算,我使用 Aurelia BindingSignaler:

我的-input.js

import {bindable, inject} from 'aurelia-framework';
import {BindingSignaler} from 'aurelia-templating-resources';

@inject(BindingSignaler)
export class MyInputCustomElement {
    @bindable val;

    constructor(signaler) {
        this.signaler = signaler;
    }

    myOnBlur() {
      console.log("blur");
      this.signaler.signal('mySignal');
    }

    valChanged() {
      console.log("val changed: " + this.val);
    }
}

我的问题是更新行总计在 Chrome 中工作得很好,但我也需要它在 Microsoft IE11 和 Edge 中工作,最后这两个浏览器显示不同的行为。如果我更改一个值并移动到下一个输入字段,什么也不会发生,但我会再次移动,第一次移动后会发生我预期的更新。

如果我查看我合并到代码中的日志条目,我可以看到在 Chrome 中首先调用 valChanged() 然后触发模糊,而 IE 11 以相反的方式执行此操作,先触发模糊,然后然后调用 valChanged()。

我尝试在 valChanged() 内部发送信号,虽然到那时 val 已更新,但此时仍无法正确计算总数。

我错过了什么吗?关于如何在 IE11/Edge?

中解决这个问题的任何建议

模板具有以下内容html(为了更容易浏览而格式化):

<input type="text" 
       value.bind="val | myFormat & updateTrigger:'blur':'paste'" 
       class="form-control" 
       blur.trigger="myOnBlur()">

html 被浏览器解析,导致 DOM 节点被 Aurelia 的 ViewCompiler "compiled" 。此编译步骤涉及枚举 DOM 节点 and their attributes,查找所有绑定、行为等

鉴于上面的模板,您希望 DOM 以它们在 html 中出现的相同顺序列出属性:type,然后是 value.bind ,然后是 class,最后是 blur.trigger,这最终会导致两次订阅元素的 blur 事件,第一个是 value 绑定 / updateTrigger,第二个是 blur.trigger。这是它在 chrome 中的工作方式,但在 Internet Explorer / Edge 中,blur.trigger 出现在 value.bind 之前,导致您看到的行为。 运行 下面的代码片段可以明白我的意思。

let input = document.querySelector('input');
console.log('attributes: ' + Array.from(input.attributes).map(a => a.name).join(', '));
<input type="text" 
       value.bind="val | myFormat & updateTrigger:'blur':'paste'" 
       class="form-control" 
       blur.trigger="myOnBlur()">

在 Chrome 中,结果将是:

在 Edge 中,结果将是: