我目前正在关注使用Web API创建电话目录的在线教程。一切都很好,直到我开始使用javascript与knockout.js绑定我的视图模型。现在没有数据加载到页面上。
当我尝试通过像http://localhost:{port_no}/api/Data/1
这样的目录访问特定的电话号码ID时,我的浏览器会尝试下载我存储数据的JSON数据。
有人可以解释为什么会发生这种情况以及为什么JSON数据没有被正确解析?
控制器类:
namespace TelephoneDirectory.Controllers
{
public class DataController : ApiController
{
public async Task<IEnumerable<TelephoneEntry>> Get()
{
using (var context = new DataContext())
{
return await context.TelephoneEntries.ToListAsync();
}
}
public async Task<TelephoneEntry> Get(int id)
{
using (var context = new DataContext())
{
return await context.TelephoneEntries.FirstOrDefaultAsync(t => t.Id == id);
}
}
public async Task<int> Post([FromBody] TelephoneEntry telephoneEntry)
{
using (var context = new DataContext())
{
if (telephoneEntry.Id == 0)
{
context.Entry(telephoneEntry).State = EntityState.Added;
}
else
{
context.Entry(telephoneEntry).State = EntityState.Modified;
}
await context.SaveChangesAsync();
return telephoneEntry.Id;
}
}
}
}
index.js(包含ko绑定的代码)
function TelephoneEntry(data) {
var self = this;
self.id = data.id;
self.firstName = data.firstName;
self.lastName = data.lastName;
self.number = data.number;
}
function TelephoneViewModel() {
var self = this;
self.id = ko.observable(0);
self.firstName = ko.observable('');
self.lastName = ko.observable('');
self.number = ko.observable('');
self.addText = ko.observable('Add');
self.resetText = ko.observable('Reset');
self.selectedIndex = -1;
self.add = function () {
var entry = new TelephoneEntry({
id: self.id(),
firstName: self.firstName(),
lastName: self.lastName(),
number: self.number()
});
if (self.addText() == 'Add') {
self.telephoneEntries.push(entry);
}
else {
var oldTelephoneEntry = self.telephoneEntries()[self.selectedIndex];
self.telephoneEntries.replace(oldTelephoneEntry, entry);
}
self.post(entry);
self.reset();
};
self.reset = function () {
self.id(0);
self.firstName('');
self.lastName('');
self.number('');
self.addText('Add');
self.resetText('Reset');
self.selectedIndex = -1;
};
self.load = function () {
$.getJSON('http://localhost:16257/api/Data/', function (data) {
$.each(data, function (index, item) {
self.telephoneEntries.push(new TelephoneEntry({
id: item.id,
firstName: item.firstName,
lastName: item.lastName,
number: item.number
}));
});
});
};
self.post = function (telephoneEntry) {
$.post('http://localhost:16257/api/Data/', telephoneEntry, function (id) {
telephoneEntry.id = id;
});
};
self.telephoneEntries = ko.observableArray([]);
self.load();
}
ko.applyBindings(new TelephoneViewModel());
WebApiConfig类:
namespace TelephoneDirectory.App_Start
{
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
}
Global.asax中
public class Global : HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
Database.SetInitializer(new Initializer());
}
}
的index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/site.css" rel="stylesheet" />
</head>
<body>
<script src="Scripts/jquery-1.9.0.min.js"></script>
<script src="Scripts/knockout-3.1.0.js"></script>
<script src="Scripts/index.js"></script>
<div class="container-narrow">
<div class="row">
<h1>Telephone Directory</h1>
</div>
<div class="row shaded padded">
<div class="col-sm-3">
<label for="firstName">First Name</label>
<input id="firstName" name="firstName" type="text" class="form-control" data-bind="value: firstName" required="required" />
</div>
<div class="col-sm-3">
<label for="lastName">Last Name</label>
<input id="lastName" name="lastName" type="text" class="form-control" data-bind="value: lastName" required="required" />
</div>
<div class="col-sm-3">
<label for="phoneNumber">Phone Number</label>
<input id="phoneNumber" name="phoneNumber" type="text" class="form-control" data-bind="value: number" required="required" />
</div>
<div class="col-sm-12">
<button id="add" name="add" type="submit" data-bind="click: add, text: addText">Add</button>
<button id="reset" name="reset" type="reset" data-bind="click: reset, text: resetText">Reset</button>
</div>
</div>
</div>
<div class="container-narrow">
<div class="row">
<table class="table table-striped">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
<th> </th>
</tr>
</thead>
<tbody data-bind="foreach: telephoneEntries">
<tr>
<td><span data-bind="text: firstName"></span></td>
<td><span data-bind="text: lastName"></span></td>
<td><span data-bind="text: number"></span></td>
<td>
<a href="#" data-bind="click: $parent.edit">Edit</a> <a href="#" data-bind="click: $parent.delete">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>{"id":1,"firstName":"Jon","lastName":"Preece","number":"4444"}
答案 0 :(得分:2)
要在文档准备就绪时设置绑定,请执行以下操作。
更改此
ko.applyBindings(new TelephoneViewModel());
到这个
$(function(){
ko.applyBindings(new TelephoneViewModel());
});