knockout js - access variable inside object - knockout-3.0

I am trying to create a computed variable (RateDisplay) based on what the user enters(MinRate, MaxRate if VRAChecked is true, else FlatRate) that is defined as an observable. I have an object (product) as part of the viewmodel like the following:
var viewModel = new function () {
var self = this;
self.Id = ko.observable();
self.product = {
Id: ko.observable(),
Name: ko.observable(),
VRAChecked: ko.observable(false),
MinRate: ko.observable(),
MaxRate: ko.observable(),
FlatRate: ko.observable(),
RateDisplay: ko.computed(function() {
if (self.product.VRAChecked())
{
return self.product.MinRate() + "-" + self.product.MaxRate();
}
else
{
return self.product.FlatRate();
}
}, this),
PercentageGoal: ko.observable()
};
};//viewmodel ends
The problem is, I get this js error: "self.product is undefined" at the line
if (self.product.VRAChecked())
I understand that, that is probably because the object is still being created.
So, how do I create the computed variable (RateDisplay)? I need it to be an element of that object (product).

The problem is that you're creating the computed before the other product properties are even created, and then, they are not defined yet.
Try to create it only after the product declaration, and it will work like a charm.
Take a look at the example below:
var viewModel = function() {
var self = this;
self.Id = ko.observable();
self.product = {
Id: ko.observable(),
Name: ko.observable(),
VRAChecked: ko.observable(false),
MinRate: ko.observable(),
MaxRate: ko.observable(),
FlatRate: ko.observable(),
PercentageGoal: ko.observable()
};
self.product.RateDisplay = ko.computed(function() {
if (self.product.VRAChecked()) {
return self.product.MinRate() + "-" + this.product.MaxRate();
} else {
return self.product.FlatRate();
}
}, self)
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<label>Min Rate <input type="textbox" data-bind="value: product.MinRate"></label>
<label>Max Rate <input type="textbox" data-bind="value: product.MaxRate"></label>
</div>
<div>
<label>Flat Rate <input type="textbox" data-bind="value: product.FlatRate"></label>
</div>
<div>
<label><input type="checkbox" data-bind="checked: product.VRAChecked"> VRA Checked</label>
</div>
<div>Display: <span data-bind="text: product.RateDisplay"></span></div>

Related

Knockoutjs Multiselect shows index instead of text value when using viewbag

I'm using a viewbag to load the options for a multi-select list. However, when I do that I'm getting a 1-based index instead of the actual text value.
<td> #Html.DropDownList("MAMUserGroupName", (MultiSelectList)ViewBag.MAMUserGroupsList, new { multiple = "multiple", data_bind = "selectedOptions:MAMUserGroups" })</td>
Here's the viewModel:
var viewModel = new UserModel([
{
id: ko.observable(""), firstName: ko.observable(""), lastName: ko.observable(""),MAMUserGroups: ko.observable()
}
]);
When the value is selected and I call the knockout save function, the value is 1, 2, and/or 3, instead of the actual text value; in this case "Group1", "Group2", "Group3"
When I do it the standard way of hard-coded options like here it works as expected: Knockout selectedOptions example. But in my case I need to load it from the viewbag.
The #Html.DropdownList is a server side rendering of the list and knockoutjs is a client side rendering of the list and the two do not know about each other. What you need to do is either render the list to a javascript array on they page, or retrieve it via Ajax/fetch from the server then render it client side. So using your code examples, i would be filling you knockoutjs view model with the data you need. something like the following.
var PageModel = function(data) {
var users = ko.observableArray();
var userGroups = ko.observableArray();
var mappedUsers = data.Users.map(function(user) {
return {
id: ko.observable(user.id),
firstName: ko.observable(user.firstName),
lastName: ko.observable(user.lastName),
mameUserGroups: ko.observableArray()
};
});
users(mappedUsers);
var mappedGroups = data.MAMUserGroups.map(function(item) {
return {
id: item.id,
name: item.name
};
});
userGroups(mappedGroups);
return {
users: users,
userGroups: userGroups
};
};
ko.applyBindings(new PageModel({
//****** Data loaded here ******
Users: [{
id: 1,
firstName: "test",
lastName: "user 1"
}, {
id: 2,
firstName: "test",
lastName: "user 2"
}, {
id: 3,
firstName: "test",
lastName: "user 3"
}, {
id: 4,
firstName: "test",
lastName: "user 4"
}],
MAMUserGroups: [{
id: 1,
name: "User Group 1"
}, {
id: 2,
name: "User Group 2"
}, {
id: 3,
name: "User Group 3"
}, {
id: 4,
name: "User Group 4"
}]
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
<tbody data-bind="foreach: users">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td>
<select data-bind="options: $parent.userGroups, selectedOptions: mameUserGroups, optionsText: 'name' " size='5' multiple='true'> </select>
</td>
</tr>
</tbody>
</table>
<ul data-bind="foreach: users">
<li>
<span data-bind="text: firstName"></span><span data-bind="text: lastName"></span>
<ul data-bind="foreach: mameUserGroups">
<li data-bind="text: name"></li>
</ul>
</li>
</ul>
<!--
<script type="text/javascript">
// Render the data on the page server side to then be used client side
$().ready(function(){
var users = #(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.Users)));
var mamUserGroups = #(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.mamUserGroups)));
});
</script>
-->
EDIT Ajax implementation
This is one way to do it. probably more code than is needed but i like to break things up into separate area of responsibility. If you try running this snippet from here what you will get is an error alert and a finished alert for the users and user groups.
var app = window.app || {};
app.modelMap = (function() {
function userMap(user) {
return {
id: ko.observable(user.id),
firstName: ko.observable(user.firstName),
lastName: ko.observable(user.lastName),
mameUserGroups: ko.observableArray()
};
}
function userGroupMap(userGroup) {
return {
id: userGroup.id,
name: userGroup.name
};
}
return {
userMap: userMap,
userGroupMap: userGroupMap
}
})();
app.data = (function() {
function getUserGroups() {
return $.get("<MAMUSerGroup_URL_HERE>").then(function(data) {
alert("successfully retrieved user group data");
return data.map(app.modelMap.userGroupMap);
})
.fail(function() {
alert("error");
})
.always(function() {
alert("finished");
});
};
function getUsers() {
return $.get("<Users_URL_HERE>").then(function(data) {
alert("successfully retrieved user data");
return data.map(app.modelMap.userMap);
})
.fail(function() {
alert("error");
})
.always(function() {
alert("finished");
});
}
return {
getUserGroups: getUserGroups,
getUsers: getUsers
}
})();
app.pageModel = (function() {
var users = ko.observableArray();
var userGroups = ko.observableArray();
function getUsers() {
return app.data.getUsers().done(users);
}
function getUserGroups() {
return app.data.getUserGroups().done(userGroups);
}
function activate() {
getUsers();
getUserGroups();
}
var vm = {
users: users,
userGroups: userGroups,
activate: activate
};
return vm;
})();
var vm = app.pageModel;
vm.activate();
ko.applyBindings(vm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

Load tabs with Ajax

I have a bootstrap nav-tab and I want to display dynamically content when I select a tab. Each tab must display a div with some text that is returned from ajax call at the controller's action GetSection().
<div class="tabbable">
<ul class="nav nav-tabs" data-bind="foreach: sections">
<li data-bind="css: { active: isSelected }">
<a href="#" data-bind="click: $parent.selectedSection">
<span data-bind="text: name" />
</a>
</li>
</ul>
<div class="tab-content" data-bind="foreach: sections">
<div class="tab-pane" data-bind="css: { active: isSelected }">
<span data-bind="text: 'In section: ' + retValue" />
</div>
</div>
</div>
Javascript code:
var Section = function (name, selected) {
this.name = name;
this.retValue = "";
this.isSelected = ko.computed(function () {
return this === selected();
}, this);
}
var ViewModel = function () {
var self = this;
self.selectedSection = ko.observable();
self.sections = ko.observableArray([
new Section('Tab One', self.selectedSection),
new Section('Tab Two', self.selectedSection),
new Section('Tab Three', self.selectedSection)
]);
self.selectedSection(self.sections()[0]);
self.selectedSection.subscribe(function () {
$.ajax({
url: '#Url.Action("GetSection")',
data: { name: self.selectedSection().name },
type: 'GET',
success: function (data) {
self.selectedSection().retValue=data.text;
}
});
});
}
ko.applyBindings(new ViewModel());
The problem is that retValue from ajax is not displayed. The controller action is this:
public JsonResult GetSection(string name)
{
var ret = new { text = name + "abcd" };
return Json(ret, JsonRequestBehavior.AllowGet);
}
Knockout can only know to update the view for properties that are obsverable (hence the name), so you need to make retValue observable:
var Section = function (name, selected) {
this.name = name; // <-- consider similar change here too
this.retValue = ko.observable(""); // <-- change here
this.isSelected = ko.computed(function () {
return this === selected();
}, this);
}
Then, you need to remember to set an obsverable's value by calling it as a method with the new value as its only argument, e.g.:
$.ajax({
url: '#Url.Action("GetSection")',
data: { name: self.selectedSection().name },
type: 'GET',
success: function (data) {
self.selectedSection().retValue(data.text); // <-- change here
}
});
And finally, if you're binding to a complex expression in your view you need to invoke it as a function (with no arguments) to get its value:
<span data-bind="text: 'In section: ' + retValue()" />
As a side note, realize that you can leave off the parentheses (consider it syntactic sugar from knockout) if you bind straight to just the observable, e.g.:
<span data-bind="text: retValue" />
Which is effectively equivalent to:
<span data-bind="text: retValue()" />
On a foot note, I see you've used this syntax for a click binding:
...
This works... but only by coincidence. You should realize these things together:
$parent.selectedSection contains the result of ko.observable() which means it is in fact a function that can be invoked
the click data-binding will invoke the expression it gets as a function, passing the contextual data (in your case a Section) to that function
So bascially, when the click happens, this happens:
$parent.selectedSection($data) // where $data == the current Section
Which effectively selects the Section.
It would be more verbose though a lot clearer if the $parent had a function:
var self = this;
self.selectChild = function(section) {
// Possibly handle other things here too, e.g. clean-up of the old selected tab
self.selectedSection(section);
}
And then use the click binding in this clear way:
...
On click the selectChild method will be called, again with the contextual data as the argument.
Instead of this
self.selectedSection().retValue=data.text;
Do this
self.selectedSection(data);

give default value to md-autocomplete

How to pass default value in md-autocomplete?
Image 1 : HTML code
Image 2 : JS code
Image 3 : Output
As you can see, I am not getting any default country as output. Is there any way to do that?
Assign yr SearchText the default value & selectedItem the object.
$scope.local ={
...
searchText : 'Default Value',
selectedItem : 'Default object'
...
}
I write small codepen with autocomplete and default value.
What you must do:
Init main model.
Define model field, used in autocomplete md-selected-item property.
Define callback for loading autocomplete items.
Before save main model extract id (or other field) from associated field.
Main error in your code here:
$scope.local = {
...
selectedItem: 1, // Must be object, but not integer
...
}
(function(A) {
"use strict";
var app = A.module('app', ['ngMaterial']);
function main(
$q,
$scope,
$timeout
) {
$timeout(function() {
$scope.user = {
firstname: "Maxim",
lastname: "Dunaevsky",
group: {
id: 1,
title: "Administrator"
}
};
}, 500);
$scope.loadGroups = function(filterText) {
var d = $q.defer(),
allItems = [{
id: 1,
title: 'Administrator'
}, {
id: 2,
title: 'Manager'
}, {
id: 3,
title: 'Moderator'
}, {
id: 4,
title: 'VIP-User'
}, {
id: 5,
title: 'Standard user'
}];
$timeout(function() {
var items = [];
A.forEach(allItems, function(item) {
if (item.title.indexOf(filterText) > -1) {
items.push(item);
}
});
d.resolve(items);
}, 1000);
return d.promise;
};
}
main.$inject = [
'$q',
'$scope',
'$timeout'
];
app.controller('Main', main);
}(this.angular));
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.js"></script>
</head>
<body ng-app="app" flex layout="column" layout-margin ng-controller="Main">
<md-content layout="column" class="md-whiteframe-z1" layout-margin>
<md-toolbar>
<div class="md-toolbar-tools">
<h3>Form</h3>
</div>
</md-toolbar>
<md-content class="md-whiteframe-z1">
<div class="md-padding">
<md-input-container>
<label for="firstname">First name</label>
<input type="text" name="firstname" ng-model="user.firstname" />
</md-input-container>
<md-input-container>
<label for="lastname">Last name</label>
<input type="text" name="lastname" ng-model="user.lastname" />
</md-input-container>
<md-autocomplete md-selected-item="user.group" md-items="item in loadGroups(filterText)" md-item-text="item.title" md-search-text="filterText">
<md-item-template>{{ item.title }}</md-item-template>
<md-not-found>No items.</md-not-found>
</md-autocomplete>
</div>
</md-content>
</md-content>
<md-content class="md-whiteframe-z1" layout-margin>
<md-toolbar>
<div class="md-toolbar-tools">
<h3>Model as JSON</h3>
</div>
</md-toolbar>
<md-content class="md-padding">
<p>
{{ user | json }}
</p>
</md-content>
</md-content>
</body>
I know this is an old question, but some people may benefit from my solution. I struggled with the problem of the model for the auto-complete being asynchronous and having my autocompletes as part of an ng-repeat. Many of the solutions to this problem found on the web have only a single auto complete and static data.
My solution was to add another directive to the autocomplete with a watch on the variable that I want to set as default for the auto complete.
in my template:
<md-autocomplete initscope='{{quote["Scope"+i]}}' ng-repeat='i in [1,2,3,4,5,6,7,8]'
class='m-1'
md-selected-item="ScopeSelected"
md-clear-button="true"
md-dropdown-position="top"
md-search-text="pScopeSearch"
md-selected-item-change='selectPScope(item.label,i)'
md-items="item in scopePSearch(pScopeSearch,i)"
md-item-text="item.label"
placeholder="Plowing Scope {{i}}"
md-min-length="3"
md-menu-class="autocomplete-custom-template"
>
then in my module:
Details.directive('initscope', function () {
return function (scope, element, attrs) {
scope.$watch(function (){
return attrs.initscope;
}, function (value, oldValue) {
//console.log(attrs.initscope)
if(oldValue=="" && value!="" && !scope.initialized){
//console.log(attrs.initscope);
var item = {id:0, order:0,label:attrs.initscope?attrs.initscope:"" }
scope.ScopeSelected = item;
scope.initialized = true;
}
});
};
});
this checks for changes to the quote["Scope"+i] (because initially it would be null) and creates an initial selected item and sets the autocompletes' selected item to that object. Then it sets an initialized value to true so that this never happens again.
I used timeout to do this.
$timeout(function() {
$scope.local = {selectedItem : 1}
}, 2000);

How to stop explorer Json downloading strange bahaviour?

i can not bind Json data to table. Also internet explorer wants to download Json data. How to stop explorer download request and fill table. i have been reading more stackoverflow questions and googling articles. i can not understand why knockout.js cannot bind data. i have been learned binding arhitecture in knockout and json binding.
like That:
http://jsfiddle.net/madcapnmckay/3rRUQ/1/
http://jsfiddle.net/rniemeyer/5EWDG/
i would like to use binding theese methods. but i can not stopping iexplorer downloading behavior.
var result = function () {
$.ajax({
type: "get",
url: "/Contact/GetEmployees/",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
viewModel = ko.mapping.fromJS(data, self.Employees);
},
error: function (error) {
alert(error.status + "<--and--> " + error.statusText);
}
});
};
ko.utils.arrayMap(result, function (i) { Directory.list.push(new Employee(i.EmployeeCode, i.EmployeeName)); });
also :
#{
ViewBag.Title = "GetPerson";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>GetPerson</h2>
<script type="text/javascript">
function Person(FirstName, LastName, Friends) {
var self = this;
self.FirstName = ko.observable(FirstName);
self.LastName = ko.observable(LastName);
self.FullName = ko.computed(function () {
return self.FirstName() + ' ' + self.LastName();
})
self.Friends = ko.observableArray(Friends);
self.AddFriend = function () {
self.Friends.push(new Person('new', 'friend'));
};
self.DeleteFriend = function (friend) {
self.Friends.remove(friend);
};
}
var viewModel = new Person();
$(document).ready(function () {
$.ajax({
url: 'Person/GetPerson',
dataType: 'json',
type: 'GET',
success: function (jsonResult) {
viewModel = ko.mapping.fromJS(jsonResult, mapping);
console.log(viewModel);
ko.applyBindings(viewModel);
}
});
});
var mapping = {
create: function (options) {
var person = options.data,
friends = ko.utils.arrayMap(person.Friends, function (friend) {
return new Person(friend.FirstName, friend.LastName);
});
return new Person(person.FirstName, person.LastName, friends);
}
};
</script>
#using (Html.BeginForm())
{
<p>First name: <input data-bind="value: FirstName" /></p>
<p>Last name: <input data-bind="value: LastName" /></p>
<p>Full name: <span data-bind="text: FullName" /></p>
<p>#Friends: <span data-bind="text: Friends().length" /></p>
#*Allow maximum of 5 friends*#
<p><button data-bind="click: AddFriend, text:'add new friend', enable:Friends().length < 5" /></p>
#*define how friends should be rendered*#
<table data-bind="foreach: Friends">
<tr>
<td>First name: <input data-bind="value: FirstName" /></td>
<td>Last name: <input data-bind="value: LastName" /></td>
<td>Full name: <span data-bind="text: FullName" /></td>
<td><button data-bind="click: function(){ $parent.DeleteFriend($data) }, text:'delete'"/></td>
</tr>
</table>
}
Controller Method:
public class PersonController : Controller
{
//
// GET: /Person/
public ActionResult GetPerson()
{
Person person = new Person
{
FirstName = "My",
LastName = "Name",
Friends = new List<Person>
{
new Person{FirstName = "Friend", LastName="Number1"},
new Person{FirstName = "Friend", LastName="Number2"}
}
};
return Json(person, "text/html", JsonRequestBehavior.AllowGet);
//return Json(person, JsonRequestBehavior.AllowGet); Not working
}
}
How to solve binding and downloading problem?

load data from db knockoutjs + mv3

attached the file EXAMPLE: http://jsfiddle.net/brux88/9fzG4/1/
hi,
I'm starting to use knockoutjs in an asp.net mvc project.
i have a view :
<button data-bind='click: load'>Load</button>
<table>
<thead>
<tr>
<th>Cliente</th>
<th>Colli</th>
<th>Tara</th>
<th>Peso Tara</th>
<th> </th>
</tr>
</thead>
<tbody data-bind='foreach: righe'>
<tr>
<td>
<select data-bind="
value: selectedCli,
options: clienteList,
optionsText: function(item) { return item.Rscli + '-' + item.Codcli },
optionsCaption: '--Seleziona un Cliente--'"
style=" width: 150px">
</select>
</td>
<td >
<input data-bind='value: Ncolli' />
</td>
<td>
<select data-bind="value: selectedTara,
options: taraList,
optionsText: function(item) { return item.Destara +
'-' + item.Codtara},
optionsCaption: '--Seleziona un Cliente--'"
style=" width: 150px">
</select>
</td>
<td >
<input data-bind="value: Ptara" />
</td>
<td>
<a href='#' data-bind='click: $parent.rimuoviRiga'>Elimina</a>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: aggiungiRiga'>Aggiungi</button>
<button data-bind='click: salva'>Salva</button>
<button data-bind='click: annulla'>Annulla</button>​
my result from data db:
[{"Codcli":4,"Rscli":"antonio","Codtart":"1002","Despar":"ciliegino","Ncolli":10,"Pcolli":100,"Codtara":"03","Destara":"","Ptara":82,"Pnetto":18,"Prezzo":1},{"Codcli":1,"Rscli":"bruno","Codtart":"1001","Despar":"pomodoro","Ncolli":10,"Pcolli":100,"Codtara":"03","Destara":"","Ptara":10,"Pnetto":90,"Prezzo":1}]
my viewmodel knockoutjs:
<script type="text/javascript">
var listCli= [{Codcli: 1,Rscli: "Bruno"},{Codcli: 2,Rscli: "Pippo"},{Codcli: 3,Rscli: "Giacomo"}];
var listTa= [{Codtara: 01,Destara: "Plastica",Pertara:4},{Codtara: 02,Destara: "Legno",Pertara:6},{Codtara: 03,Destara: "Ploto",Pertara:8}];
var mydataserver = [{"Codcli":3,"Rscli":"Giacomo","Ncolli":10,"Codtara":"03","Destara":"Legno","Ptara":82},{"Codcli":1,"Rscli":"Bruno","Ncolli":10,"Codtara":"02","Destara":"Plastica","Ptara":10}];
var RigaOrdine = function () {
var self = this;
self.selectedCli = ko.observable();
self.clienteList = ko.observableArray(listCli);
self.Ncolli = ko.observable();
self.selectedTara = ko.observable();
self.taraList = ko.observableArray(listTa);
self.Ptara = ko.observable();
self.Ncolli.subscribe(function () {
self.Ptara(self.Ncolli() ? self.selectedTara().Pertara * self.Ncolli() : 0);
});
self.selectedTara.subscribe(function () {
self.Ptara(self.Ncolli() ? self.selectedTara().Pertara * self.Ncolli() : self.selectedTara().Pertara);
});
};
var Ordine = function () {
var self = this;
self.righe = ko.observableArray([new RigaOrdine()]); // Put one line in by default
// Operations
self.aggiungiRiga = function () {
self.righe.push(new RigaOrdine());
};
self.rimuoviRiga = function (riga) {
self.righe.remove(riga);
};
self.salva = function() {
var righe = $.map(self.righe(), function (riga) {
return riga.selectedCli() ? {
Codcli: riga.selectedCli().Codcli,
Rscli: riga.selectedCli().Rscli,
Ncolli: riga.Ncolli(),
Codtara: riga.selectedTara().Codtara,
Ptara: riga.Ptara(),
} : undefined;
});
alert( ko.toJSON(righe));
//save to server
/* $.ajax({
url: "/echo/json/",
type: "POST",
data: ko.toJSON(righe),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
}
});*/
self.righe([new RigaOrdine()]);
};
//load from server
self.load = function() {
$.ajax({ url: '/echo/json/',
accepts: "application/json",
cache: false,
statusCode: {
200: function (data) {
alert(ko.toJSON(mydataserver));
//i do not know apply to viewmodel
},
401: function (jqXHR, textStatus, errorThrown) {
alert('401: Unauthenticated');
// self.location = "../../Account/Login.html?returnURL=/Index.html";
}
}
});
};
self.annulla = function() {
self.righe([new RigaOrdine()]);
};
};
var viewmodel = new Ordine();
ko.applyBindings(viewmodel);
​
</script>
if I want to load data from a db, how do I? Whereas there are dropdownlist
Your question is a bit weak so I will give you a more general answer.
To answer your question regarding how to load data from a db, it looks like that you have started on the right track. Usually you use an AJAX request to do the async request of data. To do this, knockoutJS provides the following function:
$.getJSON("/some/url", function(data) {
// Now use this data to update your view models,
// and Knockout will update your UI automatically
})
Source: http://knockoutjs.com/documentation/json-data.html
In the callback provided you will have access to the data returned from the server. It depends on the logic of your application what you want to do here - for some applications it might make sence to update the state of the viewmodel to make corresponding updates in the view.
If your question is more specific, please elaborate. Otherwise, I hope I got you on the right track.
As i can see.. you may want some good pratice to load.
I'll share with you mine.
Well.. return a Json as an JsonResult.
// POST: /Client/LoadClient
[HttpPost]
public JsonResult LoadClient(int? id)
{
if (id == null) return null;
var client = _business.FindById((int) id);
return Json(
new
{
id = cliente.id,
name = cliente.name,
list = cliente.listOfSomething.Select(s => new {idItemFromList = s.idWhatever, nameItemFromList = s.nameWhatever})
});
}
JS
viewmodel.Client.prototype.LoadClient= function (id) {
var self = this;
if (id == 0) {
return null;
}
$.ajax({
url: actionURL("LoadClient", "Client"),
data: { id: parseInt(id) },
dataType: "json",
success: function (result) {
if (result != null)
self.Load(result);
}
});
Load method.
viewmodel.Client.prototype.Load = function (result) {
var self = this;
self.idClient(result.id);
self.nameCliente(result.name);
self.ListOfSomething(result.list);
};
and..
ko.applyBinding(yourModel);
as u can see I'm using prototype it's a good practice too.

Resources