0
votes

I have several text input components to handle different types of input (e.g. alpha-only, alpha-numeric, and free-form). I could create separate components for each input type, but really, they would all be identical except for the binding attribute (e.g. alphaText below).

e.g.

 <input type="text" data-bind="
  attr: {
    id: id,
  },
  alphaText: model
 ">

Is there a way to dynamically assign a template in the viewModel based on a parameter (e.g. type:'numeric' below)

<div data-bind="
    component: {
      name: 'textField',
      params: {
         type: 'numeric',
         model: fieldModel,
       }
    }">
</div>

Alternatively, is there a way to dynamically manipulate the data-bind values from within the viewModel?

1
That's what observables are for. Bind to the observables and change the values. - Jeff Mercado

1 Answers

0
votes

Sure, you can have selectable templates within a component. It's just a matter of having a template binding on some element in the component's template, with the binding to an observable in the component's viewmodel (whose value is passed in as a param).

ko.components.register('textField', {
  viewModel: function(params) {
    this.model = ko.observable(params.type);
  },
  template: {
    element: 'text-field'
  }
});

var vm = {
  fieldModel: ko.observable('alpha')
};

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<template id="text-field">
  <template id="numeric">
    This is a numeric template
  </template>
  <template id="free-form">
    This is a free-form template
  </template>
  <div>This is a textField</div>
  <div data-bind="template: model"></div>
</template>

<div data-bind="
    component: {
      name: 'textField',
      params: {
         type: 'numeric',
         model: fieldModel,
       }
    }">
</div>
<div data-bind="
    component: {
      name: 'textField',
      params: {
         type: 'free-form',
         model: fieldModel,
       }
    }">
</div>