简体   繁体   English

knockoutjs“检查”绑定在Safari和IE中无法正常工作

[英]knockoutjs “checked” binding not working correctly in Safari and IE

I have built a pricing calculator for different document types that gives you a final price based on the number of pages, quality and quantity in your document. 我为不同的文档类型构建了一个定价计算器,根据文档中的页数,质量和数量为您提供最终价格。

The pricing is generated by a service and the data for each request is outputted as a JSON object which is than used on the calculator. 定价由服务生成,每个请求的数据作为JSON对象输出,而不是在计算器上使用。

So far everything works well in Chrome or Firefox, but not in Safari or IE. 到目前为止,一切都适用于Chrome或Firefox,但不适用于Safari或IE。 I have been able to narrow down that the issue is with the Quality radio buttons. 我已经能够缩小质量单选按钮的问题。

The issue is that the pricing in Safari for example, is always incorrect when you use the "Quality" radio buttons. 问题是,当您使用“质量”单选按钮时,Safari中的定价总是不正确。 It seems that the first click on the radio button is not firing and you always get the incorrect price. 似乎第一次单击单选按钮没有触发,你总是得到不正确的价格。

I've set up an example on jsfiddle with instructions on how to repro the issue: https://jsfiddle.net/IntricatePixels/f21dtr8j/ 我在jsfiddle上建立了一个示例,说明如何重现问题: https ://jsfiddle.net/IntricatePixels/f21dtr8j/

The example of JSFiddle should have all the details but I'd be happy to provide more info here on this post if necessary. JSFiddle的例子应该包含所有细节,但如果有必要,我很乐意在这篇文章中提供更多信息。

<div class="form-group document-quality">
    <label>Quality</label>
    <fieldset data-role="controlgroup">
        <div class="field-container" data-bind="foreach:categoryOptions, valueUpdate: 'afterkeydown', event: { change: onSubmit }" id="documentQuality">
            <label class="btn btn-default document-quality-label" data-bind="css: { 'active': $parent.selectedCategoryValue() === value }"></label>
            <div class="radio-container">
                <label class="btn btn-default document-quality-label" data-bind="css: { 'active': $parent.selectedCategoryValue() === value }">
                    <input data-bind="attr: {value: value}, checked: $parent.selectedCategoryValue" id="uniqueQuestionName" name="uniqueQuestionName" type="radio">
                </label>
            </div>
            <label class="btn btn-default document-quality-label" data-bind="css: { 'active': $parent.selectedCategoryValue() === value }"><span data-bind="text: label"></span></label>
        </div>
    </fieldset>
</div>
<div class="form-group quantity">
    <label>Quantity</label>
    <input data-bind="value: copies, valueUpdate: 'keyup'" id="numberofCopies" type="text">
</div>

Though the codes might seem confusing I would say thanks to you I've found some tricks to knockout that I didn't it can be done in that way (but I doubt I would use though :D). 虽然代码可能看起来令人困惑,但我要感谢你,我已经找到了一些淘汰的技巧,我没有这样做可以这样做(但我怀疑我会使用尽管:D)。

But let's get back to the point, let's just say that you are tired of cleaning your code for now and you want to continue with this. 但是让我们回到这一点,让我们说你现在已经厌倦了清理你的代码而你想继续这样做。 The issue with this is with this one event: { change: onSubmit } . 这个问题出现在以下一个event: { change: onSubmit } When the function was called, the value of selectedCategoryValue is not updated yet ( note : I only tested this on IE11 , I have not available macs to use for now). 当调用该函数时, selectedCategoryValue的值还没有更新( 注意 :我只在IE11上测试过这个,我现在还没有可用的mac)。 This code which assigns the value of selectedCategoryValue only took effect after the onSubmit function executed. 分配selectedCategoryValue值的代码仅在执行onSubmit函数后生效。

<input data-bind="attr: {value: value}, checked: $parent.selectedCategoryValue" id="uniqueQuestionName" name="uniqueQuestionName" type="radio">

I tried two ways that worked. 我尝试了两种方法。

First is the brute way that i don't recommend because for some personal reason i don't like setTimeout. 首先是我不推荐的粗野方式,因为出于某些个人原因我不喜欢setTimeout。

Add setTimeout in the onSubmit function. 在onSubmit函数中添加setTimeout。

self.onSubmit = function() {
        setTimeout(function(){
            self.response("<div class='priceLoading'>Loading</div>");
            var servURL = "https://prices.azurewebsites.net/price/ProductionUS/" + ko.utils.unwrapObservable(self.selectedCategoryValue) + "/" + ko.utils.unwrapObservable(self.pages()) + "/" + ko.utils.unwrapObservable(self.copies());
            $.get(servURL, function(response) {
                self.response(response.PriceFormatted);
            });
            console.log(servURL);
        }, 100)
    }

Fiddle here . 在这里小提琴

Second is more knockouty way, utilizing the subscription of selectedCategoryValue so if the value of selectedCategoryValue changes, then call the onSubmit function. 是更knockouty方式,利用认购selectedCategoryValue所以如果价值selectedCategoryValue变化,然后调用的onsubmit功能。

Change the old subscribe callback of selectedCategoryValue to: selectedCategoryValue的旧订阅回调更改为:

self.selectedCategoryValue.subscribe(function(newValue) {
        self.onSubmit();
    });

And remove change event that calls onSubmit: 并删除调用onSubmit的更改事件:

<div class="field-container" data-bind="foreach:categoryOptions, valueUpdate: 'afterkeydown'" id="documentQuality">

Fiddle here . 在这里小提琴

And lastly, you should really upgrade your knockout library (if it's possible) so that you can utilize knockout's new cool features just like textInput to change your value, valueUpdate binding combo. 最后,你应该真正升级你的淘汰库(如果可能的话),这样你就可以利用knockout的新酷功能,就像textInput一样改变你的value, valueUpdate绑定组合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM