简体   繁体   中英

KnockoutJS losing the viewmodel

I'm having some trouble with a proof of concept. What I'm trying do is have a jQuery dialog come up when a button is clicked. The dialog contents are bound to a viewmodel and the dialog calls aa json service to retrieve some data to populate that viewmodel.

Running into two problems with the code I have here:

  • The vmAccount viewmodel will only bind if the div is visible from the initial page load
  • The vmAccount viewmodel is undefined in either SearchForCustomerAccounts or in DisplayResults despite being a global var to those

 $(function() { var vmAccount = function() { var self = this; this.Accounts = ko.observableArray(); this.Name = ko.observable('Jimmy'); }; function DisplayDialog() { $("#Dialog").dialog({ resizable: false, height: 140, modal: true, buttons: { "Search": function() { SearchForCustomerAccounts(); }, Cancel: function() { $(this).dialog("close"); } } }); } function SearchForCustomerAccounts() { console.log("Name: " + vmAccount.Name); $.ajax({ url: "api/CustomerSearchController/" + vmAccount.Name, type: "GET", dataType: "json", success: function(data) { DisplayResults(data); } }); } function DisplayResults(data) { vmAccount.Accounts.removeAll(); for (var i = 0; i < data.length; i++) { vmAccount.Accounts.push(data[i]); } }; $("#butSearch").button().on("click", function() { DisplayDialog(); }); $(document).ready(function() { ko.applyBindings(vmAccount); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script> <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <body> <button id="butSearch">Open</button> <div id="Dialog" style="visibility: visible"> <form id="Account"> <p>Customer Name</p> <input type="text" data-bind="value: Name" /> </form> </div> </body> 

I'm new to javascript and knockout so its probably something simple thats missing. Appreciate any help you guys can provide, thanks!

The code should look some thing like this, vmAccount is empty because the function is not returning anything;

var vmAccount = function() {
var self = this;
this.Accounts = ko.observableArray();
this.Name = ko.observable('Jimmy');
return this;

};

1) Your vmAccount is function, but you try to use it like instance.

2) To get value from KO's observable, you should call it (unwrap value). So use vmAccount.Name() instead of vmAccount.Name .

 $(function() { function VmAccount () { var self = this; this.Accounts = ko.observableArray(); this.Name = ko.observable('Jimmy'); }; var vmAccount = new VmAccount(); function DisplayDialog() { $("#Dialog").dialog({ resizable: false, height: 140, modal: true, buttons: { "Search": function() { SearchForCustomerAccounts(); }, Cancel: function() { $(this).dialog("close"); } } }); } function SearchForCustomerAccounts() { console.log("Name: " + vmAccount.Name()); $.ajax({ url: "api/CustomerSearchController/" + vmAccount.Name(), type: "GET", dataType: "json", success: function(data) { DisplayResults(data); } }); } function DisplayResults(data) { vmAccount.Accounts.removeAll(); for (var i = 0; i < data.length; i++) { vmAccount.Accounts.push(data[i]); } }; $("#butSearch").button().on("click", function() { DisplayDialog(); }); $(document).ready(function() { ko.applyBindings(vmAccount); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script> <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <body> <button id="butSearch">Open</button> <div id="Dialog" style="visibility: visible"> <form id="Account"> <p>Customer Name</p> <input type="text" data-bind="value: Name" /> </form> </div> </body> 

 $(function() { var vmAccount = { Accounts : ko.observableArray(), Name : ko.observable('Jimmy'), }; function DisplayDialog() { $("#Dialog").dialog({ resizable: false, height: 140, modal: true, buttons: { "Search": function() { SearchForCustomerAccounts(); }, Cancel: function() { $(this).dialog("close"); } } }); } function SearchForCustomerAccounts() { console.log("Name: " + vmAccount.Name()); $.ajax({ url: "api/CustomerSearchController/" + vmAccount.Name(), type: "GET", dataType: "json", success: function(data) { DisplayResults(data); } }); } function DisplayResults(data) { vmAccount.Accounts.removeAll(); for (var i = 0; i < data.length; i++) { vmAccount.Accounts.push(data[i]); } }; $("#butSearch").button().on("click", function() { DisplayDialog(); }); $(document).ready(function() { ko.applyBindings(vmAccount); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script> <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <body> <button id="butSearch">Open</button> <div id="Dialog" style="visibility: visible"> <form id="Account"> <p>Customer Name</p> <input type="text" data-bind="value: Name()" /> </form> </div> </body> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM