knockout javascript object issue - asp.net

I am stuck at the approach for binding javascript objects to knockout observable arrays.I am using asp.net .I am lost at assigning the response data from ajax call to the javascript object.
My aspx page
<table id="gvActivityForm" class="test">
<th class="thdata">
TestSample
</th>
<tbody data-bind="foreach: arraytoadd">
<tr>
<td data-bind="text: testid"></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
var TemplateFunction = function()
{
var self = this;
self.testid= ko.observable(0);
} //end
RealFunction = function ()
{
var self = this;
self.arraytoadd = ko.observableArray([]); //Adding an array
self.addevent = function()
{
self.arraytoadd.push(new TemplateFunction());
}
} //end of javascript object
objRealFunction = new realFunction();
ko.applyBindings(objRealFunction);
I am getting the data through ajax call .
$.ajax({ //start ajax call for posting and getting the data back
type: 'POST',
url: 'PopupWebService.asmx/ReceiveandSendJobActivity',
data: JSON.stringify({item:obj}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
for(var i=0;i<response.d.length;i++)
{
TemplateFunction.testid= response.d[i].TestId; //My question is how do I assign the data .I am lost here
}
script>

You haven't instantiated any instances of your 'TemplateFunction'
When your data comes back from your ajax call - do something like this using your objRealFunction object:
success: function (response) {
for(var i=0;i<response.d.length;i++)
{
var templateFunction = new templateFunction();
templateFunction.testId(response.d[i].testId);
objRealFunction.arraytoadd.push(templateFunction)
}
}
You'll also need to update your view as at the moment it's expecting a property called testId on each member of the observableArray.
You will need to change your html binding to
foreach: arrayToAdd().templateFunction
as you have defined your testId property as a ko.observable() on the templateFunction object

knockout observables are treated as functions so in order for you to set the value of an observable you cannot user regular assignment operator syntax but rather pass the new value as a parameter to the knockout observable function:
TemplateFunction.testid(response.d[i].TestId);

Related

Should AntiForgeryToken be inside or outside of the loop?

We currently has this code
#foreach (var market in Model.Markets.Markets)
{
<li>
#using (Html.BeginForm("Set", "Market", new {marketId = market.Value}, FormMethod.Post, null))
{
#Html.AntiForgeryToken()
<button class="btn btn-none market-list__item jsSelectMarket">
<img src="#market.FlagUrl" class="market-selector__market-icon">
<p class="market-selector__market-text">#market.Text</p>
</button>
}
</li>
}
It looks correct, but profiling shows that a lot of CPU time is spent in generating the anti-forgery tokens (basically 20 times per page for this only).
Is there a way to move #Html.AntiForgeryToken() outside of the foreach so it is only called one?
Thanks.
You should go with Ajax.
You can try with following code for generic method of post
function AjaxPostMethod(url, formName, parameters, successCallback) {
$.validator.unobtrusive.parse($(formName));
$(formName).validate();
if ($(formName).valid()) {
var form = $(formName);
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
type: 'POST',
url: url,
data:
{
__RequestVerificationToken: token,
model: parameters
},
success: successCallback,
error: function (xhr, textStatus, errorThrown) {
console.log('error');
}
});
}
Everything in one go

Knockoutjs not binding to element

I am kind of new to KnockoutJS and trying to use it.
I am having trouble binding the element using knockoutjs. Please see the fiddle below and help in resolving and correcting me.
It is basically not binding the value to the span element.
http://jsfiddle.net/EpyRA/
HTML:
<div id="taxyear">
<table style="width: 100%;" cellpadding="4" cellspacing="4">
<tr>
<td style="width: 25%">
<span>Name:</span><span data-bind="value: ReturnData.Name"></span>
</td>
</tr>
</table>
</div>
Javascript:
var myWeb = myWeb || {};
$(function () {
(function (myWeb) {
"use strict";
var serviceBase = '../Services/Data.asmx/',
getSvcUrl = function (method) { return serviceBase + method; };
myWeb.ajaxService = (function () {
var ajaxGetJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: "GET",
data: jsonIn,
dataType: "json",
contentType: "application/json",
success: function (json) {
callback(json);
}
});
},
ajaxPostJson = function (method, jsonIn, callback) {
var test = { "Name": "testRaju", "SourceID": "ABCD" };
//just return data instead of calling for testing
callback(test);
};
return {
ajaxGetJson: ajaxGetJson,
ajaxPostJson: ajaxPostJson
};
})();
} (myWeb));
(function (myWeb) {
"use strict";
myWeb.DataService = {
getReturnData: function (jsonIn, callback) {
myWeb.ajaxService.ajaxPostJson("GetReturnData", jsonIn, callback);
}
};
} (myWeb));
//Constructor for a ReturnData object
myWeb.ReturnData = function () {
this.Name = ko.observable();
this.SourceID = ko.observable();
},
//View Model
myWeb.prdviewmodel = (function () {
var prd = ko.observable();
loadReturnDataCallback = function (jsonReturnData) {
alert(jsonReturnData.Name);
prd = new myWeb.ReturnData()
.Name(jsonReturnData.Name)
.SourceID(jsonReturnData.SourceID);
},
loadReturnData = function () {
myWeb.DataService.getReturnData("{'YearID':'" + 22 + "'}", myWeb.prdviewmodel.loadReturnDataCallback);
};
//public
return {
loadReturnData: loadReturnData,
loadReturnDataCallback: loadReturnDataCallback,
ReturnData: prd
}
})();
//hookup knockout to our viewmodel
myWeb.prdviewmodel.loadReturnData();
ko.applyBindings(myWeb.prdviewmodel);
});
Thanks in Advance,
Sam
I see a couple of minor issues:
When binding against a span, you would want to use the text binding rather than the value binding.
In the AJAX callback, you would want to set the prd observable's value by calling it as a function, rather than setting it as a new value.
In the UI, you can make use of the with binding to ensure that it does not try to bind to a property of the observable, before it has been loaded.
Here is an updated fiddle: http://jsfiddle.net/rniemeyer/Bdz5a/

knockout.js with binding

This is probably a really basic question but in the following view model I am populating self.userData from an ajax call. I want to display this information in the UI and I figured the 'with' binding is the way to go.. however since self.userData is empty until the ajax function is called I get an error from the with binding
HTML
<div data-bind="with: userData">
<div data-bind="text: userId"></div>
...
</div>
Model
var viewModel = function () {
var self = this;
self.userData = {};
self.login = function(data) {
var postData = { ..trimmed out.. };
$.ajax({
type: "POST",
url: "myService",
data: postData
}).done(function (data, status) {
self.userData = ko.mapping.fromJS(data, userData);
console.log(self.userData);
}).fail(function (data, status) {
alert('Could Not Login');
});
}
};
ko.applyBindings(new viewModel());
Initialize userData with an empty observable, an then set it with the object created by the the mapping plugin once the call return. I.e. change
self.userData = {};
with
self.userDara = ko.observable();
and change
self.userData = ko.mapping.fromJS(data, userData);
with
self.userData(ko.mapping.fromJS(data,userData));
You need to initialize userData as an empty observable (single object from ajax call) or observable array (multiple objects) first:
self.userData = ko.observableArray([]);
or
self.userData = ko.observable();

Questions about knockout

1.i have 2 question about knockout on asp.net.
server side method:
<WebMethod>
Public Shared Function foo() As List(Of person)
Return New List(Of person)() From {New person With {.id = 1, .fname = "meysam"},
New person With {.id = 2, .fname = "yasaman"}}.ToList
End Function
json and binding to knockout:
var VM = {};
$.getJSON("default.aspx/foo", function (data) {
var tmp = JSON.stringify(data.d);
VM.model =
ko.applyBindings(VM);
});
html:
<div data-bind="foreach: model">
<h3 data-bind="text: id">
</h3>
<p>
Name: <span data-bind="text: fname"></span>
</p>
but when i run in browser.No nothing will happen.fname,id Will be displayed.
2.what The difference between $.getJSONand dataType:json?
$.getJSON("default.aspx/foo", function (data) {
var tmp = JSON.stringify(data.d);
});
and
$.ajax({
type:"post",
url:"default.aspx/foo",
contentType:"application/json;charset=utf-8",
dataType:"json",
success:function(data){}
})
So, this really should be two actual questions, but anywho (in reverse order!):
2: From the jQuery documentation: $.getJSON is a shorthand Ajax function, which is equivalent to:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback
});
So they are the same.
1: Your attempt to call JSON.stringify() on the result of a getJSON call is redundant. getJSON already does that. The problem is two-fold: neither of those parsers can parse .net lists (I might be wrong about this, but I am 60% sure). In either case, the better solution would be to serialize the list into JSON in the web method, and return already parsed JSON. .NET has this ability built-in.
Two, your list doesn't have a d property. So even when you sort that part out, you are going to get an undefined error.
About your knockout question:
Here's code to solve your issue:
Output
ASPX code behind
[WebMethod]
public static IEnumerable<KnoPerson> GetPeople()
{
return Builder<KnoPerson>.CreateListOfSize(10).Build();
}
public class KnoPerson
{
public int ID { get; set; }
public int FirstName { get; set; }
}
ASPX
<script type="text/javascript" src="Scripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="Scripts/knockout-2.1.0.js"></script>
<script type="text/javascript" src="Scripts/knockout.mapping-latest.js"></script>
<script type="text/javascript">
$(function () {
var model = {};
$.ajax({
url: "KnockoutBindingFromPageMethod.aspx/GetPeople",
data: null,
type: "POST",
dataType: "json",
contentType: "application/json",
cache: false,
async: false,
success: function (myData) {
model.people = ko.mapping.fromJS(myData.d);
model.yo = ko.observable("plop");
ko.applyBindings(model);
},
error: function (xhr) {
alert(xhr.responseText);
}
});
});
</script>
<div data-bind="text: yo"></div>
<div data-bind="foreach: people">
<h3 data-bind="text: ID"></h3>
<p>
Name: <span data-bind="text: FirstName"></span>
</p>
</div>
2.what The difference between $.getJSONand dataType:json?
.getJSON is a shortcut, and it internally uses .ajax
The .getJSON function sets the following properties:
dataType: “json”
type: "GET"

Ajax success when a view is returned

I'm struggling to return a view or partial view with Ajax. Whenever I change the return type to something that isn't JSon the ajax command never succeeds. I need to return a partial view because I want to return a lot of data back.
This is my current code:
(Controller)
[HttpPost]
public ActionResult AjaxTestController(string Input)
{
string Results = Input + " -- TestTestTest";
return PartialView("Test", Results);
//return new JsonResult() { };
}
(View)
function AjaxTest() {
alert("test");
$.ajax({
type: "POST",
url: "Home/AjaxTestController",
data: "Input=Test11111",
success: function () {
alert("Success!");
}
});
Thanks!
You can use the $.post command for that:
function AjaxTest() {
alert("test");
$.post({
url: "Home/AjaxTestController",
data: "Input=Test11111",
success: function (response) {
alert(response);
}
});
try the following:
$(function () {
$('#submit').live('click', function () {
AjaxTest();
});
});
function AjaxTest() {
$.ajax({
type: "POST",
url: '#Url.Action("AjaxTestController", "Home")',
data: { Input: "Test - " + new Date() },
success: function (data) {
$('#partialResult').html(data);
},
error: function (xhr, err) {
alert(xhr.responseText);
}
});
};
inside your view and ensure that you have your target div set up for the partial to be populated into:
<div id="partialResult"></div>
also, for the example above, I added a button to the view to initiate the ajax (purely for testing):
<input type="button" value="Submit" id="submit" />
your 'partialview' should look something like this:
#model string
<h2>
Partial Test</h2>
<p>
#Model
</p>
no other changes are required to the existing action for this to now function as required.
[UPDATE] - I changed the AjaxTest() method to include the error event (the result of which is captured in an alert). hopefully, this may help further.
partial View is different than view you have to specify the whole path to the partial view or have it in share folder. otherwise is going to return not found and never success. any way this always work for me, try
partialView("~/Views/ControllerView/Test.cshtml")

Resources