【问题标题】:How to prevent Knockout from overwriting my initial checkbox value?如何防止 Knockout 覆盖我的初始复选框值?
【发布时间】:2015-10-13 22:45:05
【问题描述】:

我有一个通过浏览器正常加载并使用 Laravel 填充的表单,但使用 Knockout.js 和 AJAX 对服务器进行页面更新:

{{ Form::checkbox('launch_time_change', 'launch_time_change', true, array('data-bind' => checked: emailNotifications.launch_time_change')) }} 

这里的第三个参数代表页面加载时checkbox的状态,可以看到是勾选了。

但是,我想随后将此值发送到 Knockout,以便可以在服务器上更新复选框而无需重新加载页面。这需要将复选框值存储在ko.observable() 中,但每当我尝试将checked 绑定应用到我的复选框字段时,默认状态都会被覆盖。

在上述情况下,最初在页面加载时选中的复选框在 Knockout 初始化 ViewModel 中的可观察对象时变为未选中状态。这是expected behaviour,很遗憾:

KO 设置元素的选中状态以匹配您的参数值。任何先前检查的状态都将被覆盖。

我怎样才能阻止这种情况发生?

【问题讨论】:

  • 您对淘汰赛视图模型有什么控制权?你不能只正确初始化 observable 吗?
  • 如果在构建页面的过程中不能直接正确设置observable,至少可以运行一些额外的JS代码,取实际checkbox的值,在viewmodel中设置observable你打电话给applyBindings
  • @JamesThorpe,完全控制,但我也不愿意发出单独的 AJAX 请求来下载数据。我可以在 applyBindings 之前初始化 observables,但我以前从未这样做过,所以我不知道它是如何工作的。
  • 将复选框值传递给视图模型构造函数并将其设置为可观察对象

标签: javascript forms checkbox knockout.js


【解决方案1】:

好吧,考虑到我的应用程序主要基于 Laravel,我选择了一条完全不同的路线。

我决定使用Jeffrey Way's laracasts/utilities repo 创建一个Javascript 外观,这样我可以将Javascript 变量放到我的视图中,如下所示:

    JavaScript::put([
        'emailSubscriptions' => someValue
    ]);

这比在全球任何地方都可以访问,在附加到 window 对象的命名空间变量中:

console.log(laravel.emailSubscriptions) // "someValue"

它不应该污染全局范围,因为在config.php

/*
|--------------------------------------------------------------------------
| JavaScript Namespace
|--------------------------------------------------------------------------
|
| By default, we'll add variables to the global window object.
| It's recommended that you change this to some namespace - anything.
| That way, from your JS, you may do something like `Laracasts.myVar`.
|
*/
'js_namespace' => 'laravel'

工作得很好,而且它可以在任何地方访问,而不仅仅是内联。无需通过构造函数传递或发出单独的 AJAX 请求。

【讨论】:

    【解决方案2】:

    使用 Knockout 的替代方法是创建一个不会覆盖输入值的新 value 绑定。

    ko.bindingHandlers.dont_clear_init_value = _.extend({},
      ko.bindingHandlers.value,
      {
        init: function(element, valueAccessor, allBindings) {
          if (ko.isObservable(valueAccessor()))
            valueAccessor()(ko.selectExtensions.readValue(element));
    
          ko.bindingHandlers.value.init(element, valueAccessor, allBindings);
        }
      }
    );
    

    如何在模板中使用。

    <p>Login name: <input data-bind="dont_clear_init_value: userName" /></p>
    <p>Password: <input type="password" data-bind="dont_clear_init_value: userPassword" /></p>
    
    <script type="text/javascript">
        var viewModel = {
            userName: ko.observable(),
            userPassword: ko.observable(),
        };
    </script>
    

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      相关资源
      最近更新 更多