-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
It would be amazing to be able to generate view models based on ApiControllers. Here is what I mean:
[RoutePrefix("api/person")]
public class PersonApiContoller : ApiContoller{
[Route("")]
[HttpGet]
public async Task<Person[]> GetAll(){
return await dbContext.People.ToListAsync();
}
[Route("create")]
[HttpPost]
public async Task<Guid> CreatePerson(CreatePersonRequest toCreate){
Guid ret = Guid.NewGuid();
dbContext.People.Add(new Person(){ Id =ret, FirstName= toCreate.FirstName, DateOfBirth = toCreate.DateOfBirth});
await dbContext.SaveChangesAsync();
return ret;
}
}
public class CreatePersonRequest
{
public string FirstName{get;set;}
public DateTime DateOfBirth {get;set;}
}
public class Person
{
public Guid Id {get;set;}
public string FirstName{get;set;}
public DateTime DateOfBirth{get;set;}
}
======= GENERATES ==========
class PersonViewModel {
private urlBase: string;
constructor(urlBase: string){
this.urlBase = urlBase + "/api/person";// found from the RoutePrefix attribute
}
GetAll() : JQueryPromise<Person[]>{
// HttpGet attribute means we can use $.getJSON
$.getJSON(this.urlBase + ""/*found from the Route attribute*/);
}
CreatePerson(person: CreatePersonRequest) : JQueryPromise<string/*aka, GUID*/> {
// HttpPost attribute means we need to use $.post
return $.post(this.urlBase + "/create"/*found from the Route attribute*/, ko.toJS(person));
}
}
// Return type from the API
// Preferred over interface
type Person = {
Id: string; // aka, GUID
FirstName: string;
DateOfBirth: Date;
}
// may or may not want to generate an edit version
class PersonEdit {
Id: string; // not observable
FirstName: KnockoutObservable<string>; // perferred over FirstName(): string; KnockoutObservable is more than just a function
DateOfBirth: KnockoutObservable<Date>;
constructor(initial?:Person){
this.Id = initial && initial.Id;
this.FirstName = ko.observable(initial && initial.FirstName);
this.DateOfBirth = ko.observable(initial && initial.DateOfBirth);
}
}
// input type should be observable
class CreatePersonRequest {
FirstName: KnockoutObservable<string>;
DateOfBirth: KnockoutObservable<Date>;
constructor(initial?:Person){
this.FirstName = ko.observable(initial && initial.FirstName);
this.DateOfBirth = ko.observable(initial && initial.DateOfBirth);
}
}
====== USAGE =======
// typically extend view model to add client side stuff
// could also compose a view model from multiple generated view models
class MyPersonViewModel extends PersonViewModel {
CustomerList: KnockoutObservableArray<Person>;
ActiveCustomer: KnockoutObservable<Person>;
EditCustomer: KnockoutComputed<EditPerson>;
constructor(urlBase: string){
super(urlBase);
this.CustomerList = ko.observableArray();
this.ActiveCustomer = ko.observable(null);
this.EditCustomer = ko.pureComputed((newVal) => {
return newVal && new EditPerson(newVal);
});
}
LoadCustomerList() : void {
this.GetAll().then((list) => this.CustomerList(list));
}
SelectCustomer(customer: Person) : void {
this.ActiveCustomer(customer);
}
SaveCustomer() : JQueryPromise<string> {
if(!this.ActiveCustomer()){
throw 'No Customer Selected.';
}
return this.CreatePerson(new CreatePersonRequest(ko.toJS(this.ActiveCustomer()));
}
}
@section scripts{
<script>
var vm = new MyPersonViewModel ('@Url.Content("~/")');
$(function(){
vm.LoadCustomerList();
ko.applyBindings(vm);
});
</script>
}
I would gladly do the work if you could help me understand the project.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels