如何防止Knockout覆盖我的初始复选框值

How to prevent Knockout from overwriting my initial checkbox value?

本文关键字:复选框 我的 何防止 Knockout 覆盖      更新时间:2023-09-26

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

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

这里的第三个参数表示页面加载时复选框的状态,如您所见,它已被选中。

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

在上面的例子中,当Knockout初始化ViewModel中的可观察对象时,在页面加载时被选中的复选框将被取消选中。遗憾的是,这是预期的行为:

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

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

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

我决定使用Jeffrey Way的laracasts/utilities repo来创建一个Javascript facade,在那里我可以把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请求。

使用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>