Adding Model Properties - ldco2016/microurb_web_framework GitHub Wiki

I now have the ability to handle events inside my View class, now the next thing I need to work on is ensure I can print up information from a Model inside of my template.
So my UserForm does not have a lot of direct reference to a User Model, except to print out the users' current name.
The UserShow does have a lot more information that needs to be printed out from the User Model.
Nonetheless, I do think I should try to implement this functionality inside of UserForm and eventually extract it so I can use it inside of UserShow as well.
I want to ensure that whenever I create an instance of a View, I pass in a Model and then print out properties from that Model into my template.
In my UserForm.ts
class file, I am going to say that whenever I create an instance of a UserForm
, I want to pass in a second argument like so:
import { User } from "../models/User";
export class UserForm {
constructor(public parent: Element, public model: User) {}
eventsMap(): { [key: string]: () => void } {
return {
"click:button": this.onButtonClick,
};
}
onButtonClick() {
console.log("Howdy");
}
template(): string {
return `<div>
<h1>User Form</h1>
<input />
<button>Click Me</button>
</div>`;
}
bindEvents(fragment: DocumentFragment): void {
const eventsMap = this.eventsMap();
for (let eventKey in eventsMap) {
const [eventName, selector] = eventKey.split(":");
fragment.querySelectorAll(selector).forEach((element) => {
element.addEventListener(eventName, eventsMap[eventKey]);
});
}
}
render(): void {
const templateElement = document.createElement("template");
templateElement.innerHTML = this.template();
this.bindEvents(templateElement.content);
this.parent.append(templateElement.content);
}
}
So now I am expecting to get access to a User Model whenever I create an instance of this UserForm
. Now I can go back into my index.ts
file and ensure I create an instance of a user and pass it into my form when it gets created.
Inside my index.ts
, I now get an error around UserForm
because I am passing it one argument, when it is expecting 2. So I can import User
like so:
import { UserForm } from "./views/UserForm";
import { User } from "./models/User";
const root: Element = document.getElementById("root")!;
const userForm = new UserForm(root);
userForm.render();
And then create an instance of a User
using that static class property of buildUser
because buildUser
already has all those predefined submodules inside of it like so:
import { UserForm } from "./views/UserForm";
import { User } from "./models/User";
const user = User.buildUser({ name: "NAME", age: 20 });
const root: Element = document.getElementById("root")!;
const userForm = new UserForm(root, user);
userForm.render();
Now I have passed in that user
as my second argument to UserForm
constructor.
Last thing i have to do is go to UserForm
and ensure I reference all the properties a user
has and ensure I print them up inside of my template.
import { User } from "../models/User";
export class UserForm {
constructor(public parent: Element, public model: User) {}
eventsMap(): { [key: string]: () => void } {
return {
"click:button": this.onButtonClick,
};
}
onButtonClick() {
console.log("Howdy");
}
template(): string {
return `<div>
<h1>User Form</h1>
<div>User name: ${this.model.get("name")}</div>
<div>User age: ${this.model.get("age")}</div>
<input />
<button>Click Me</button>
</div>`;
}
bindEvents(fragment: DocumentFragment): void {
const eventsMap = this.eventsMap();
for (let eventKey in eventsMap) {
const [eventName, selector] = eventKey.split(":");
fragment.querySelectorAll(selector).forEach((element) => {
element.addEventListener(eventName, eventsMap[eventKey]);
});
}
}
render(): void {
const templateElement = document.createElement("template");
templateElement.innerHTML = this.template();
this.bindEvents(templateElement.content);
this.parent.append(templateElement.content);
}
}
I will head back over to the browser and I can now see my users name and age: