Adding Model Properties - ldco2016/microurb_web_framework GitHub Wiki

Screen Shot 2021-08-31 at 12 30 27 PM

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:

Screen Shot 2021-09-08 at 1 59 16 PM

⚠️ **GitHub.com Fallback** ⚠️