knockout.js: using a containerless foreach on a &l

2019-01-15 08:44发布

问题:

In RP Niemeyer's article Knockout.js Performance Gotcha #3 - All Bindings Fire Together, an approach to building a dropdown list is provided:

<select data-bind="value: selectedOption">
    <!-- ko foreach: options -->
    <option data-bind="attr: { value: id }, text: name"></option>
    <!-- /ko -->
</select>

This code is also in a jsfiddle from the article.

http://jsfiddle.net/rniemeyer/QjVNX/

However, when I employed this method of building a select in a project, it was working just fine, until I tested in Internet Explorer 8. IE8 failed and was "unable to parse bindings".

Indeed, running the fiddle from the article in IE8 also results in an error. Is there a way to build the select in IE8 (I assume IE8 or less) using knockout's foreach?

回答1:

Yes, that is definitely an issue. I will have to update the post. IE will strip comments from inside the select.

Here is an issue that we saw on github that is similar: https://github.com/SteveSanderson/knockout/issues/578

One solution is to use Michael Best's repeat binding: https://github.com/mbest/knockout-repeat.

One of the things that it allows you to do is repeat a single element multiple times with a different context. So, in that case it would act similar to the containerless syntax, just without the comments.

Sample with repeat: http://jsfiddle.net/rniemeyer/QjVNX/

You can also choose to use the other technique from the article (isolatedOptions), unless you need more control over your option elements.



回答2:

Although this is an issue, there is really no need to use a 'foreach' here. Knockout includes the 'options' binding for a select that quite happily works in IE8.

Please see the documentation here: http://knockoutjs.com/documentation/options-binding.html

<select data-bind="value: selectedOption">
    <!-- ko foreach: options -->
    <option data-bind="attr: { value: id }, text: name"></option>
    <!-- /ko -->
</select>

Can be changed to:

<select data-bind="value: selectedOption, options: options, optionsText: function(item) {return item.name}, optionsValue: function(item) {return item.id}></select>

Hope this helps.