9

我有一个简单的复选框,它的值由我正在编写的一些基础设施调整,以在 localStorage 中保持状态。我知道这通常可以通过设置 viewModel 来完成,但基础设施不知道任何淘汰绑定并且无法访问它们。

我不认为这会是一个问题,因为我认为淘汰赛正在运行“更改”事件,但是$checkbox.prop('checked', true).trigger('checked')未能触发我的 observable。即使直接使用 click 事件也不能满足我的需要。

淘汰赛与哪些事件有关?如何让它读取控件的状态?

jsbin 在这里显示了这种奇怪的行为。尝试直接选择复选框而不是单击按钮。

4

7 回答 7

2

我找到了一种更好的方法。只需将此代码放入您的 domready 事件中:

    $("input:checkbox").bind('change', function () {
        $(this).triggerHandler('click');
    });
于 2013-11-25T17:42:06.630 回答
1

淘汰赛绑定并没有真正按照您的想法工作。

查看: http: //knockoutjs.com/documentation/custom-bindings.html

这是您可以使用的一种解决方案,没有 jQuery,没有自定义绑定。

您的 html 将保持不变。

var m = {
  isChecked: ko.observable(false),
  infrastructureUpdatesCheckbox: function() {
    this.isChecked( this.isChecked() === true ? false : true);
  }
};

ko.applyBindings(m);
于 2013-01-03T17:19:13.600 回答
1

您应该通过视图模型更改复选框的选中状态:

 var m = {
   isChecked: ko.observable(false)
  //,infrastructureUpdatesCheckbox: function() {
    //$chk = $(':checkbox');
    //$chk
    //  .prop('checked', !$chk.prop('checked'))
    //  .trigger('change');
    //this.isChecked(!this.isChecked());  // this - is your view model
 }
};

这是更新版本:

function InfrastructureUpdatesCheckbox(){

  var $cb = $(':checkbox');
  var cb = $cb[0];
  cb.checked = !cb.checked;  // manually change checked status
  $cb.triggerHandler('click');  // run all event handlers bound to 'click' event
}

我猜这个问题仅与复选框(单选按钮)有关。当您手动触发事件时,其他控件的行为应该正确。

于 2013-01-03T18:13:48.307 回答
1

您可能已经找到了解决问题的方法,但这可能对其他人有所帮助。

我有完全相同的问题。我所做的是使用 pub-sub 模式并让我的组件触发它自己的更改事件。然后您可以做的是让需要更新模型的基础设施组件的实例订阅该事件,然后更新您的模型。更好的是,您的模型可以订阅事件,这样您的模型就知道基础设施组件,而不是相反

这样,您的基础架构组件就不需要了解 ko,您可以在其他任何地方重复使用它。如果您打算重新使用该组件,我相信您找到它的其他用途只是时间问题。

希望这会有所帮助(抱歉,没有代码,因为我无法在 SO 上发布客户代码,但如果有人想要一个示例,就这么说吧,我会做一个 jsfiddle 来说明。

于 2013-12-10T13:12:46.647 回答
1

在我的情况下,这与一个 jquery 错误有关。我使用 github 淘汰问题跟踪器来追踪这个问题;看这里

最终我最终在我的组件中这样做了:

var isjQueryOld = /^(0|1)\.[0-8]\./.test($.fn.jquery); // <=1.8.*
var toggleCheckbox = isjQueryOld ? jQueryOldToggleCheckbox : function($el) { $el.trigger('click') } //https://github.com/knockout/knockout/issues/987


function jQueryOldToggleCheckbox($el) {
    //This should be simple right? See http://stackoverflow.com/a/8595601/5056
    //and "simulating events to adjust knockout models" jasmine spec
    //all this is nessessary to get everything working with knockout
    var changeTo = !$el.prop('checked');
    if(changeTo)
        $el.attr('checked', true);
    else
        $el.removeAttr('checked');
    $el.trigger('click');
    $el.prop('checked', changeTo);
}

在我的代码中

        toggleCheckbox($el);
于 2013-12-10T16:10:09.247 回答
0

我不知道什么事件敲除正在侦听,您可能会涉足源本身并弄清楚,但一种解决方案是使用自定义绑定。在init自定义绑定中,您可以为要捕获的任何事件(例如changed)设置您想要的任何处理程序,并使用它来强制您绑定运行update

于 2013-01-03T19:05:44.643 回答
0

我今天花了几个小时使用检查和单击方法陷入点击循环,尝试 ko.observable、pureComputed 写入甚至是基础设施更新检查框,但没有成功太久,无法向任何为我的工作付费的人解释为什么我无法检查该死的淘汰赛中的单选按钮。不幸的是,我的上下文(带有购买插件的 Magento 2 结帐)不允许我实现有效的视图模型,所以最后我设法通过简单的 hack 解决了这个问题,添加了第二个输入 type="radio" 并在点击时显示它:

selectRadioPayment: function (obj, event, method) {
        this.selectPaymentMethod(obj, event, method);
        $('.ko-payment-selector').show();
        $('#p_method_' + method).hide();
        $('#p_method_' + method).closest('.radio-payment-selector').show();
    },

    renderedPaymentMethods: function() {
        if(quote.paymentMethod) {
            var selectedMethod = quote.paymentMethod().method;
            $('#p_method_' + selectedMethod).hide();
            $('#p_method_' + selectedMethod).closest('.radio-payment-selector').show();
        }
    },

    <input class="radio-payment-selector" type="radio" class="hidden" checked />
    <input class="ko-payment-selector" type="radio" name="payment[method]" class="radio" event: {change: function(data, event){$parent.selectRadioPayment(data, event, $data.method)}}"/>

我希望有一天它会对某人有所帮助。

于 2018-08-26T02:09:27.217 回答