asp.net mvc - Binding with multiple PartialViews in Knockout -


enter image description here

i've got jquery accordion , each panel contains form. of forms same, , inputs share same ids, names, , data-bind attributes.

assuming each form has different binding context (using ko with:), this how set knockout.js viewmodel if there two forms.

however, don't know in advance how many forms there be. i'm rendering partialview (which contains form) every form object in mvc viewmodel's collection of forms.

@model viewmodel  <div class="container-fluid">     <div id="jqueryaccordion">          @foreach (var form in model.allforms.tolist())         {            <!-- ko with: items[@form.key] -->            html.renderpartial("_form", form);            <!-- /ko -->          }          // etc. 

how set knockout.js viewmodel if don't know how many forms there going be?

as anh bui suggested, create them dynamically in browser. using applybindings markup created asp.net on server-side bit of hack , means working against knockout, not it.

it better let knockout take care of creating forms. means

  1. supplying data needs create each form json
  2. creating knockout template form markup
  3. looping on data foreach binding

the template:

<script type="text/html" id="form-template">   <form action="/target-url">     <label for="user_name">what's name?</label>     <input type="text" data-bind="value: user_name" name="user_name" />     <label for="user_location">where from?</label>     <input type="text" data-bind="value: user_location" name="user_location" />   </form> </script> 

next output relevant form data json array on server side. haven't used asp.net, can offer pseudo-code here:

<script type="application/javascript">   window.form_json_from_server = "     @foreach (var form in model.allforms.tolist())    {      // .. asp.net json output magic goes here    }    "; </script> 

so end result in markup looks like

<script type="application/javascript">   window.form_json_from_server = "[     { user_name: "foo1", user_location: "bar1" },    { user_name: "foo2", user_location: "bar2" },    { user_name: "foo3", user_location: "bar3" }    ]"; </script> 

(note js strings cannot contain line breaks. i've formatted here line breaks easier reading)

now have our form data formatted json, saved in javascript string. next up: knockout view model:

var viewmodel = function viewmodel() {   var = this,       raw_forms_object;    // reconstitute our json string javascript object   raw_forms_object = json.parse(window.form_json_from_server);    // objects made our json end in   this.forms = ko.observablearray([]);    ko.utils.arrayforeach(raw_forms_object, function(f) {     // f contains 1 of our form objects, such { user_name: "foo1", user_location: "bar1" }      // instead of adding f directly array, make new object in     // properties observables     var form = {       user_name: ko.observable(f.user_name),       user_location: ko.observable(f.user_location),     };      // add our new form object our observablearray     // make sure use 'that', because 'this' scope of arrayforeach callback we're in     that.forms.push(form);   }); } 

now have observablearray called 'forms' on our view model our form objects in it. use foreach binding make many forms have form objects:

<div data-bind="template: { name: 'form-template', foreach: forms }"></div> 

all that's left applying instance of our view model page:

ko.applybindings( new viewmodel() ); 

if like, can try out in runnable code snippet:

var viewmodel = function viewmodel() {    var = this,        raw_forms_object;          // reconstitute our json string javascript object    raw_forms_object = json.parse(window.form_json_from_server);          // objects made our json end in    this.forms = ko.observablearray([]);          ko.utils.arrayforeach(raw_forms_object, function(f) {      // f contains 1 of our form objects, such      // { user_name: "foo1", user_location: "bar1" }            // instead of adding f directly array, make new object in      // properties observables      var form = {        user_name: ko.observable(f.user_name),        user_location: ko.observable(f.user_location),      };            // add our new form object our observablearray      // make sure use 'that', because 'this' scope       // of arrayforeach callback we're in      that.forms.push(form);    });  }      ko.applybindings( new viewmodel() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>    <script type="text/html" id="form-template">    <form action="/target-url">      <label for="user_name">what's name?</label>      <input type="text" data-bind="value: user_name" name="user_name" />      <label for="user_location">where from?</label>      <input type="text" data-bind="value: user_location" name="user_location" />    </form>  </script>    <div data-bind="template: { name: 'form-template', foreach: forms }"></div>    <script type="application/javascript">     window.form_json_from_server = '[{"user_name": "foo1","user_location": "bar1"},{"user_name": "foo2","user_location": "bar2"},{"user_name": "foo3","user_location": "bar3"}]';  </script>


Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -