title: Knockout.js bind array of objects to repeated <select>'s
body: <p>I've got this Knockout.js view model:</p>
  
  <pre><code>{
      "LanguageFromTos":
      [{
          "LanguageFromToId":0,
          "LanguageFromId":2,
          "LanguageFrom":null,
          "AllLanguagesFrom":[
              {"Selected":false,"Text":"English","Value":"1"},
              {"Selected":false,"Text":"French","Value":"2"},
              {"Selected":false,"Text":"Spanish","Value":"3"}
          ],
  
          "LanguageToId":1,
          "LanguageTo":null,
          "AllLanguagesTo":[
              {"Selected":false,"Text":"English","Value":"1"},
              {"Selected":false,"Text":"French","Value":"2"},
              {"Selected":false,"Text":"Spanish","Value":"3"}
          ],
          "Users":null
      }]
  }
  </code></pre>
  
  <p>And these html <code>&lt;select&gt;</code>s:</p>
  
  <pre><code>&lt;div class="LanguageFromToRow"&gt;
      &lt;input type="hidden" name="languageFromTos.index" autocomplete="off" value="c50532b0-65d2-4a81-baeb-59b768fd120f" /&gt;
  
      &lt;label for="languageFromTos_c50532b0-65d2-4a81-baeb-59b768fd120f__LanguageFromId"&gt;From&lt;/label&gt;:
      &lt;select data-bind="???" data-val="true" data-val-number="The field From must be a number." data-val-required="The From field is required." id="languageFromTos_c50532b0-65d2-4a81-baeb-59b768fd120f__LanguageFromId" name="languageFromTos[c50532b0-65d2-4a81-baeb-59b768fd120f].LanguageFromId"&gt;
          &lt;option value="1"&gt;English&lt;/option&gt;
          &lt;option selected="selected" value="2"&gt;French&lt;/option&gt;
          &lt;option value="3"&gt;Spanish&lt;/option&gt;
      &lt;/select&gt;
      &lt;span class="field-validation-valid" data-valmsg-for="languageFromTos[c50532b0-65d2-4a81-baeb-59b768fd120f].LanguageFromId" data-valmsg-replace="true"&gt;&lt;/span&gt;
  
      &lt;label for="languageFromTos_c50532b0-65d2-4a81-baeb-59b768fd120f__LanguageToId"&gt;To&lt;/label&gt;:
      &lt;select data-bind="???" data-val="true" data-val-number="The field To must be a number." data-val-required="The To field is required." id="languageFromTos_c50532b0-65d2-4a81-baeb-59b768fd120f__LanguageToId" name="languageFromTos[c50532b0-65d2-4a81-baeb-59b768fd120f].LanguageToId"&gt;
          &lt;option selected="selected" value="1"&gt;English&lt;/option&gt;
          &lt;option value="2"&gt;French&lt;/option&gt;
          &lt;option value="3"&gt;Spanish&lt;/option&gt;
      &lt;/select&gt;
      &lt;span class="field-validation-valid" data-valmsg-for="languageFromTos[c50532b0-65d2-4a81-baeb-59b768fd120f].LanguageToId" data-valmsg-replace="true"&gt;&lt;/span&gt;
  
      &lt;a href="#" class="deleteLanguageFromTo"&gt;delete&lt;/a&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>Can anyone tell me what I need to add to the <code>data-bind</code> attributes of each <code>select</code> to tie them up to the Knockout.js view model? The <code>value</code> of the first <code>select</code> should be bound to <code>LanguageFromId</code> in the view model and the <code>value</code> of the second <code>select</code> should be bound to <code>LanguageToId</code> in the view model.</p>
  
  <p><code>LanguageFromTos</code> in the view model is an array, so all of what you see inside may be repeated (2 <code>LanguageFromTos</code> would result in the <code>LanguageFromToRow</code> div being repeated twice, for example). The number of repeats is set both server-side (data posted by the controller may have multiple <code>LanguageFromTos</code>) and client-side (an 'add' button that allows the user to add another div with its contained <code>select</code>s) in different cases, so I presume Knockout's templating is a no-go as MVC needs to loop through and render each row so that it can catch them all on a 'normal' post back.</p>
  
  <p>Any help much appreciated!</p>
  
  <h2>Edit</h2>
  
  <p>Here's the MVC model for the page:</p>
  
  <pre><code>public class DirectorySearchModel
  {
      [Display(Name = "User name contains")]
      public string UserName { get; set; }
  
      [Display(Name = "First name contains")]
      public string FirstName { get; set; }
  
      [Display(Name = "Last name contains")]
      public string LastName { get; set; }
  
      [Display(Name = "Languages translated")]
      public IEnumerable&lt;LanguageFromTo&gt; LanguageFromTos { get; set; }
  }
  </code></pre>
  
  <p>Here's the <code>LanguageFromTo</code> object:</p>
  
  <pre><code>public class LanguageFromTo
  {
      [Key]
      public virtual int LanguageFromToId { get; set; }
  
      [Display(Name = "From")]
      public virtual int LanguageFromId { get; set; }
      [ForeignKey("LanguageFromId")]
      public virtual Language LanguageFrom { get; set; }
      public virtual IEnumerable&lt;SelectListItem&gt; AllLanguagesFrom { get; set; }
  
      [Display(Name = "To")]
      public virtual int LanguageToId { get; set; }
      [ForeignKey("LanguageToId")]
      public virtual Language LanguageTo { get; set; }
      public virtual IEnumerable&lt;SelectListItem&gt; AllLanguagesTo { get; set; }
  
      public virtual ICollection&lt;User&gt; Users { get; set; }
  }
  </code></pre>
  
  <p>And here's the cshtml code for the MVC view. This code sits in a partial that's repeated depending on how many <code>LanguageFromTo</code>s there are in <code>DirectorySearchModel</code> that's passed to the MVC view:</p>
  
  <pre><code>&lt;div class="LanguageFromToRow"&gt;
      @using(Html.BeginCollectionItem("languageFromTos")) {
          @: @Html.LabelFor(m =&gt; m.LanguageFromId): @Html.DropDownListFor(m =&gt; m.LanguageFromId, Model.AllLanguagesFrom, new { data_bind = "value: getLanguageFromToById(0).LanguageFromId" }) @Html.ValidationMessageFor(m =&gt; m.LanguageFromId)
          @: @Html.LabelFor(m =&gt; m.LanguageToId): @Html.DropDownListFor(m =&gt; m.LanguageToId, Model.AllLanguagesTo, new { data_bind = "value: getLanguageFromToById(0).LanguageToId" }) @Html.ValidationMessageFor(m =&gt; m.LanguageToId)
          &lt;a href="#" class="deleteLanguageFromTo"&gt;delete&lt;/a&gt;
      }
  &lt;/div&gt;
  </code></pre>