I am having trouble creating a property-dependent create/edit-view in KnockoutJS.
Here's the thing: everything I create are "People" of sorts - it could be a Healthcare Professional, Plumber, Mechanic or Engineer. Depending on what kind/type of person it is, I need to enter different data.
Here an example:
Healthcare Professional: Name, Telephone, Hospital, etc.
Plumber: Name, Telephone, Crafts, etc.
Engineer: Name, Telephone, Specialities, etc.
What I can do is create properties on my ViewModels such as "showCity", "showHospital" and so on to hide individual form-fields.
However, for the sake of separation, I would like to use entirely different forms: again, I could set the respective form to only show if the condition is met.
However, I would like KnockoutJS to only render the respective form that should be used (the Person's type is always determined when it is first created - it cannot be changed).
What I don't end-up doing is have one form that is shown and ten that are there (and data-bound) but hidden.
I tried using the "if" binding like so: <div data-bind="with: $root.selectedPerson"><form data-bind="if: $data.type='mathematician'"></form></div>
, but to no avail.
Would anybody know what the best-practice is in this case?
Your if
binding is setting the $data.type
value, not comparing it. Try:
<div data-bind="with: $root.selectedPerson"><form data-bind="if: $data.type() === 'mathematician'"></form></div>
Although this is fine, I always try to avoid code in my data-binding markup. I would try and create a computed that would return the resulting true/false of the comparison, but in your situation, you would need one for each person type, and that would get tricky. For that, I would turn to templates. You could do:
<div data-bind="template: { name: $root.selectedPerson().type, data: $root.selectedPerson }"></div>
<script type="text/html" id="mathematician">...</script>
<script type="text/html" id="plumber">...</script>
*Note: As of KO version 2.3.0, the name
property of the template
binding can accept observables. If you're using a previous version, be sure to call the observable in the binding: name: $root.selectedPerson().type()