LostInComputer
LostInComputer

Reputation: 15430

Knockout reduce if/else repetition

I have a bunch of repetitive if/else statement that I want to simply. The purpose of the statement is to render the correct element and bindings for an item.

The most repetitive part of the code is the autocomplete.

<div>
    <!-- ko if: type === 'text' -->
        <!-- ko if: hasAutocomplete() -->
            <input data-bind="textInput: val, autocomplete: { data: choices, other_parameters... }" />
        <!-- /ko -->

        <!-- ko ifnot: hasAutocomplete() -->
            <input data-bind="textInput: val" />
        <!-- /ko -->
    <!-- /ko -->

    <!-- ko if: type === 'date' -->
        <!-- ko if: hasAutocomplete -->    
            <input data-bind="dateInput: val, autocomplete: { data: choices, other_parameters... }" />
        <!-- /ko -->

        <!-- ko ifnot: hasAutocomplete -->    
            <input data-bind="dateInput: val" />    
        <!-- /ko -->
    <!-- /ko -->

    etc...

</div>

Update solution

The solution that I am thinking is to

1.Create a binding that will add the autocomplete binding by calling applyBindingsToNode if hasAutocomplete is true:

<input data-bind="dateInput: val, optionalautocomplete" />

2.Use templates instead of if binding (thanks U10!)

Is that the right solution? Any other suggestions?

Upvotes: 0

Views: 119

Answers (1)

Dmitry Zaets
Dmitry Zaets

Reputation: 3277

One of possible solutions that I see is to use templates:

<div data-bind="template: { name: type() + hasAutocomplete() ? '-autocomplere': '', data: buyer }"></div>

<script type="text/html" id="text">
     <input data-bind="textInput: val" />
</script>

<script type="text/html" id="text-autocomplete">
     <input data-bind="textInput: val, autocomplete: { data: choices }" />
</script>

<script type="text/html" id="date">
     <input data-bind="dateInput: val" />
</script>

<script type="text/html" id="date-autocomplete">
     <input data-bind="dateInput: val, autocomplete: { data: choices }" />
</script>

Or move template choosing to computed like:

this.templateName= ko.computed(function() {
    return type() + hasAutocomplete() ? '-autocomplere': '';
}, this);

Another possible solution is to create custom element.

Upvotes: 2

Related Questions