问题
I am new to knockout and asp.net webapi, but I am trying to learn. I am missing something, as i cannot perform a get(or a post,put...) here is my webapi method
public string GetAllData()
{
List<Task> llistTask = new List<Task>();
Task lobjTask = new Task();
lobjTask.title = "some title";
lobjTask.isDone = false;
llistTask.Add(lobjTask);
return Newtonsoft.Json.JsonConvert.SerializeObject(llistTask);
}
my knockout code
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/knockout-2.2.0.js"></script>
<script src="Scripts/jquery-1.8.2.min.js"></script>
</head>
<body>
<h3>Tasks</h3>
<form data-bind="submit: addTask">
Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
<button type="submit">Add</button>
</form>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
<li>
<input type="checkbox" data-bind="checked: isDone" />
<input data-bind="value: title" />
<%-- <a href="#" data-bind="click: $parent.removeTask">Delete</a>--%>
</li>
</ul>
You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s)
<span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span>
<script type="text/javascript">
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function () {
return ko.utils.arrayFilter(self.tasks(), function (task) { return !task.isDone() });
});
// Operations
self.addTask = function () {
self.tasks.push(new Task({ title: this.newTaskText() }));
self.newTaskText("");
};
self.removeTask = function (task) { self.tasks.remove(task) };
// Load initial state from server, convert it to Task instances, then populate self.tasks
$.getJSON("http://localhost:51958/api/tasks/GetAllData", function (allData) {
var mappedTasks = $.map(allData, function (item) { return new Task(item) });
self.tasks(mappedTasks);
});
}
ko.applyBindings(new TaskListViewModel());
</script>
</body>
</html>
The output is 39 rows of null data, which doesnt make sense to me. what am i missing?
回答1:
The problem is in the handling results of the $.getJSON() function. It returns you a string, not a JSON object, and when you do $.map() later you're iterating 39 characters of your string, but not the objects you need.
To fix it you need to parse your string as a JSON:
$.getJSON("http://localhost:51958/api/tasks/GetAllData", function (allData) {
allData = $.parseJSON(allData);
var mappedTasks = $.map(allData, function (item) { return new Task(item) });
self.tasks(mappedTasks);
});
Update:
I was really interested, why do you get a string instead of a real object as you should get in case of $.getJSON() function. And the reason is your WebApi method. As far as it returns a string, WebAPI engine converts it additionally to a JSON string (it doesn't care that you've already done it). As a result you have twice JSONified object and jQuery can't parse it.
All you need to do is to return not a string but a List<Task> in your WebAPI method and not to JSON it:
public List<Task> GetAllData()
{
List<Task> llistTask = new List<Task>();
...
return llistTask;
}
And you can leave your JS code as you had it (no additional parseJSON), because now you'll get a real object.
回答2:
Try using the ko.mapping plugin. It puts the individual objects in form knockout likes.
code would look like
// initial state from server, convert it to Task instances, then populate self.tasks
$.getJSON("http://localhost:51958/api/tasks/GetAllData", function (allData) {
self.tasks = ko.mapping.fromJSON(allData);
});
来源:https://stackoverflow.com/questions/13557302/how-to-consume-asp-net-webapi-with-knockout