【问题标题】:KnockoutJS Object doesn't support 'toFixed'KnockoutJS 对象不支持“toFixed”
【发布时间】:2015-02-22 21:29:36
【问题描述】:

我正在使用 KnockoutJS,但遇到了一个我不知道如何寻找解决方案的问题:

我有一个包含记录的表:

<script type="text/html" id="myItemsTemplate">
<tr>
    <td data-bind="text: MyNumber().toFixed(2)"></td>
    <td>
        <button class="btn" data-bind="click: $root.editItem">Edit</button></td>
    <td>
        <button class="btn btn-primary" data-bind="click: $root.enterHours">Enter Hours</button></td>
</tr>

最初“MyNumber().toFixed(2)”只是“MyNumber”,但我遇到了一个问题,即“MyNumber”不会显示小数位或显示超过 2 个小数位,具体取决于值(如果值为“7.00”,它将只显示“7”,如果它是“7.345345”,它将显示完整的“7.345345”)。所以我把它改成了“MyNumber().toFixed(2)”。

这似乎修复了显示,但现在似乎已经破坏了更新部分:

<script type="text/html" id="myEditTemplate">
    <tr>
        <td>
            <input data-bind="value: MyNumber" class="table-edit" /></td>
        <td>
            <button class="btn btn-success" data-bind="click: $root.acceptItemEdit">Save</button></td>
        <td>
            <button class="btn btn-warning" data-bind="click: $root.cancelItemEdit">Cancel</button></td>
    </tr>
</script>

在这里,当我尝试保存记录时,它会保存它,但也会返回错误:

错误:无法解析绑定。 消息:TypeError:对象不支持属性或方法“toFixed”; 绑定值:文本:MyNumber().toFixed(2)

我尝试更改编辑模板,使其使用: ko.utils.unwrapObservable(MyNumber()).toFixed(2) 要么 MyNumber().toFixed(2) 以匹配项目模板。这不会导致 Javascript 错误,但也不会更新值。

我看到帖子说这是因为“MyNumber”不是可观察的,所以我尝试了 unwrapObservable()。除此之外,我不确定我应该去哪里找出问题所在。

【问题讨论】:

  • 您的问题听起来很熟悉,但这个问题不允许我们重现它。请包含更多(但最少)代码来重现它,最好添加一个堆栈片段(在编辑器工具栏上)。
  • 您能否验证MyNumber 的所有值实际上是一个数字(而不是空值、字符串、对象、数组等)?
  • 尽量避免在视图中执行操作。为了更好的可维护性,请使用计算或绑定处理程序。

标签: javascript knockout.js


【解决方案1】:

根据您的问题描述,我在这里复制了一个测试用例:http://jsfiddle.net/w2nae2dq/。 @icktoofay 有一部分是正确的:最好使用计算的 observable(但它不是必需的本身)。如果您需要显示 2 个十进制值进行编辑,您将需要一个可写的计算 observable。但是,如果您只想显示 2 个十进制数字并使 MyNumber 值可编辑,请查看 fiddle 以获取演示。

无论如何,您的代码的问题是类型转换之一。实际上,当您第一次设置 MyNumber 的值时,它是一个数字。但是,当用户在&lt;input&gt; 中输入新值(并因此更新MyNumber)时,该值被设置为字符串 值,这使得text: 无法绑定到执行toFixed 方法。所以你计算出来的 observable 看起来像这样:

self.MyNumberRounded = ko.computed(function() {
    return parseFloat(self.MyNumber()).toFixed(2); // note parseFloat
}, self);

这就是为什么Object doesn't support property :)

【讨论】:

  • 看来这是原因和解决方法。我想这也解释了为什么如果我不更改数值就不会弹出错误。
【解决方案2】:

我没有使用过 KnockoutJS,但从他们的文档看来,您需要创建一个 computed observable

this.formattedMyNumber = ko.computed(function() {
    return this.MyNumber().toFixed(2);
}, this);

然后绑定到那个:

<td data-bind="text: formattedMyNumber"></td>

如果您也想在编辑视图中使用格式化版本,您可能需要使用writable computed observables

【讨论】:

  • 这对我来说很有意义,但似乎问题比这更深。即使我使用可观察的计算机,它也会给出相同的错误。我认为 Tyblitz 的例子说明了原因。
猜你喜欢
  • 2017-06-27
  • 2011-12-03
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 2017-01-14
  • 2014-04-23
  • 2019-11-12
  • 2017-09-20
相关资源
最近更新 更多