I have this view model,
define(['text!./form.html', 'knockout', '../../home', '../../users'],
function(template, ko,homeModel,userModel) {
function registerUserViewModel() {
var self = this;
...
self.registerUser = function(){
...
$.ajax({
url: 'server/registerUser.php',
type: 'post',
data: {"data":credentials},
success: function (result) {
if(result == "Successful"){
homeModel.viewModel.addUser("Jun","5:30");
}else{
alert(result);
}
}
});
}
return self;
}
return {
viewModel: registerUserViewModel,
template: template
};
});
Here is my homeViewModel,
define(["knockout", "text!./home.html", "../../users"],
function (ko, homeTemplate, userModel) {
function homeViewModel(params) {
var self = this;
...
self.users = ko.observableArray([]);
$.ajax({
url: 'server/getUsers.php',
type: 'post',
data: {"data":id},
success: function (result) {
var row = JSON.parse(result)
for(var i=0;i<row.length;i++){
self.users.push(new userModel.userModel(row[i]["name"],row[i]["time"],row[i]["id"]));
}
}
});
self.addUser = function(name,time){
self.users.push(new userModel.userModel(name,time));
}
return self;
}
return { viewModel: homeViewModel, template: homeTemplate };
});
When I go to the page,
There is an error,
homeModel.viewModel.addUser is not a function.
but I assigned a function to self.addUser. I tried homeModel.addUser but still not working.
Is there any other way to simply add a new userModel to self.users array?
Related
I am trying to populate my combo box from the database on page load. When I debug it, debug point don't hit at adminsService.test(result) at all. Why is that? I am trying to get the data without any conditions.
angular.module('adminService', []).factory('adminService', function ($rootScope, $http) {
var modelService = function () {
}
modelService.prototype.test = function (test) {
var promise = $http(
{
method: 'POST',
url: '/Model/getTopics',
contentType: 'application/json',
data: {
test: test
}
});
return promise;
}
viewRoleModule.controller('viewRoleController', function ($scope, $routeParams, adminService) {
var self = this;
self.$onInit = function () {
self.topicRoleItems = function ()
{
adminService.test(result);
};
}
});
<div ng-repeat="item in $ctrl.topicRoleItems">
{{item.TopicName}}
</div>
Try
self.topicRoleItems = adminService.test().then(function(result){
self.topicRoleItems = result;
});
UPDATE
.factory('adminService', function ($rootScope, $http,$q) {
var modelService = [];
modelService.test = function (test) {
var deferred = $q.defer();
$http({
method: 'POST',
url: '/Model/getTopics',
contentType: 'application/json',
data: {
test: test
}
}).success(function(resp){
deferred.resolve(resp);
}).error(function(resp){
deferred.reject();
});
return deferred.promise;
}
return modelService;
})
I'm getting null for the controller parameter. I am posting data as I can see it in Chrome Developer tools. I have a Person model in MVC that matches the Person model below. This is my ViewModel :
function Person(data) {
this.FirstName = ko.observable(data.FirstName);
this.LastName = ko.observable(data.LastName);
this.Id = ko.observable(data.Id);
this.fullName = ko.computed(function () {
return this.FirstName() + " " + this.LastName();
}, this);
}
function PersonViewModel() {
var self = this;
self.people = ko.observableArray([]);
$.getJSON("/api/person/getpeople", function (allData) {
var mappedTasks = $.map(allData, function (item) { return new Person(item) });
self.people(mappedTasks);
});
self.save = function(){
$.ajax("/api/person/updateperson", {
data: ko.toJSON({ people: self.people }),
type: "post", contentType: "application/json",
success: function (result) { alert(result) }
});
}
}
ko.applyBindings(new PersonViewModel);
API controller:
[HttpPost]
public bool UpdatePerson(List<Person> person)
{
return mgr.UpdatePerson(person);
}
You need to make sure that the service parameter's names match up with what you're passing.
self.save = function(){
$.ajax("/api/person/updateperson", {
data: ko.toJSON({ person: self.people }),
type: "post", contentType: "application/json",
success: function (result) { alert(result) }
});
}
I am using MVC. In my one page, if i type one value that is process, if it exists the related details will populate in other all fields. how to do this in Ajax call?
Controller:
public ActionResult GetDetail(string pincode)
{
Partner partner= null;
if (!string.IsNullOrEmpty(pincode))
{
partner= _channelRepository.GetpartnerByPincode(pincode);
}
return View("Call",partner);
}
Call is the Aspx page.
In view:
<script type ="text/javascript">
$('#getPincode').text('Get Pincode') // Sets text for company.
.attr('href', '#');
$("#getPincode").click(function () {
$('#getPincode').text('Get Company')
.attr('href', 'GetDetail?pincode=' + $('#Pincode').val());
});
$("#Pincode").blur(function () {
$("#checkPincode").trigger('click');
});
$(document).ready(function () {
$('#checkPincode').click(function () {
var name = $('#Pincode').val();
var data = 'pincode=' + name;
$.ajax({
type: "GET",
url: "GetDetail",
data: data,
success: function (data) {
alert(data);
}
});
return false;
});
});
</script>
But i don't know how to populate the result into my view which means editor fields???
View:
<%:Html.TextBox("Address")%>
You can try this one:
public JsonResult GetDetail(string pincode)
{
Partner partner= null;
if (!string.IsNullOrEmpty(pincode))
{
partner= _channelRepository.GetpartnerByPincode(pincode);
}
return Json(partner, JsonRequestBehavior.AllowGet);
}
$(document).ready(function () {
$('#checkPincode').click(function () {
var name = $('#Pincode').val();
var data = {'pincode': name};
$.ajax({
type: "POST",
url: "/GetDetail",
data: data,
success: function (data) {
alert(data);
}
});
return false;
});
});
return it as a jsonResult
public JsonResult GetDetail(string pincode)
{
Partner partner= null;
if (!string.IsNullOrEmpty(pincode))
{
partner= _channelRepository.GetpartnerByPincode(pincode);
}
return Json(partner);
}
or if you want to load partial view load it as
public ActionResult GetDetail(string pincode)
{
Partner partner= null;
if (!string.IsNullOrEmpty(pincode))
{
partner= _channelRepository.GetpartnerByPincode(pincode);
}
return PartialView("Call",partner);
}
<div id="myDiv"></div>
$(document).ready(function () {
$('#checkPincode').click(function () {
var name = $('#Pincode').val();
var data = 'pincode=' + name;
$.ajax({
type: "GET",
url: "GetDetail",
data: data,
success: function (data) {
$('#myDiv').html(data);
}
});
return false
});
});
I have been using knockout.js for a while now, and haven't encountered this problem before. Usually, when I try to push a new js object to an observableArray, it works without an issue, but for some reason, this time around I'm getting this error:
TypeError: self.Students.push is not a function
Here is a snippet of my code:
window.ApiClient = {
ServiceUrl: "/api/students",
Start: function () {
var viewModel = ApiClient.ViewModel(ngon.ClientViewModel);
ko.applyBindings(viewModel);
viewModel.get();
}
};
ApiClient.ViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, this);
this.get = function (id) {
if (id == undefined) {
return ApiClient.Service.get(self.PageSize(), self.PageNumber(), function (data) {
self.Students(data);
});
}
}
this.post = function () {
return ApiClient.Service.post(self.DetailedStudent, function (data) {
self.Students.push(data);
});
}
return this;
}
ApiClient.Service = function () {
var _get = function (pageSize, pageNumber, callback) {
sv.shouldShowLoading = false;
var queryParams = String.format("?pageSize={0}&pageNumber={1}", pageSize, pageNumber);
$.ajax(ApiClient.ServiceUrl + queryParams, {
dataType: "json",
type: "get",
success: callback
});
}
var _post = function (student, callback) {
$.ajax(ApiClient.ServiceUrl, {
data: ko.mapping.toJSON(student),
type: "post",
contentType: "application/json; charset-utf-8",
statusCode: {
201 /*Created*/: callback,
400 /*BadRequest*/: function (jqxhr) {
var validationResult = $.parseJSON(jqxhr.responseText);
alert(jqxhr.responseText);
}
}
});
}
return {
get: _get,
post: _post
};
}();
$(document).ready(function () {
ApiClient.Start();
});
My student object is a very simple C# object that has Id, FirstName, LastName. The get() function works without any issues, it's just the callback function from the post() that cannot push the resulting data. Also, the data being returned back from the server looks correct:
{"Id":"rea","FirstName":"asdf","MiddleName":null,"LastName":"rrr"}
I solved this! It's because the initial viewModel, when being instantiated by the page's view model object had 'null' for its Students property.
knockout.js requires non-null values for all fields that are to be auto mapped.
So I am writing something using augment for inheritance and for some reason I can run this.setButtons(type) and console.log(this.buttons) in that method, but when I run my this.getButtons() it comes back as undefined, even though getButtons just returns this.buttons. Any help would be greately appreciated. I will post up all the code I have so far, because maybe I'm not inheriting properly. Thank you in advance.
var ContextMixin = function () {};
ContextMixin.prototype = {
createElements: function (el, mode, type) {
var m;
if (mode == 'exact') {
$("#" + el).append("<ul id='contextmenu'>");
} else {
$(el).each(function () {
m = $(this).append("<ul id='contextmenu'>");
});
$('body').append(m);
}
$("#contextmenu").css({
'position': 'absolute',
top: 13,
left: 13
});
var new_buttons = this.getButtons();
$.each(this.buttons['buttons'], function () {
m.append("<li id='" + this + "'>" + this + "</li>");
});
},
attachEvents: function () {
functions = this.getFunctions(type);
buttons = this.getButtons();
for (index in buttons['buttons']) {
addEvent(buttons['buttons'][index], this.functions[index][0], this.functions[index][1]);
};
},
setFunctions: function (type) {
var callback = {
success: function (msg) {
this.functions = msg;
},
failure: function () {
alert('Error getting functions')
}
};
$.ajax({
type: 'GET',
url: 'function_list.php?type=' + type,
success: function (msg) {
this.functions = msg;
}
});
},
getFunctions: function () {
return this.functions;
},
setType: function (value) {
this.type = value;
},
getType: function () {
return this.type;
},
setButtons: function (type) {
$.ajax({
type: 'GET',
url: 'button_list.php?type=' + type,
success: function (reply) {
this.buttons = reply;
}
});
},
getButtons: function () {
return this.buttons;
}
}
function createMenu(el, type, mode) {
this.setButtons(type);
this.setFunctions(type);
this.createElements(el, mode, type);
}
augment(createMenu, ContextMixin);
function augment(receivingClass, givingClass) {
if (arguments[2]) { //Only give certain methods.
for (var i = 2, len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
} else { //Give all methods
for (methodName in givingClass.prototype) {
if (!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
Because this in the callback to the AJAX request is not your object.
Here's a common fix...
setButtons: function(type) {
var self = this; // keep a reference to this
$.ajax({
type: 'GET',
url: 'button_list.php?type=' + type,
success: function(reply) {
self.buttons = reply; // use the reference here
}
});
},
...but a better fix is to use the context: property of the $.ajax request...
setButtons: function(type) {
$.ajax({
type: 'GET',
context: this, // set the context of the callback functions
url: 'button_list.php?type=' + type,
success: function(reply) {
this.buttons = reply;
}
});
},
If you change
ContextMixin.prototype = {
createElements
to
ContextMixin.prototype.createElements
it should work.
this is not what you think it is in your ajax callback—instead of being your current object, it's actually the global object the XHR object. All your callback is doing is putting a buttons property onto the xhr object.
You need to save this before your function runs:
setButtons: function(type) {
var self = this;
$.ajax({
type: 'GET',
url: 'button_list.php?type=' + type,
success: function(reply) {
alert(reply);
self.buttons = reply;
}
});
},