1

I have written custom HTML elements whose constructors and definitions themselves are in classes. I have done this in order to create a view. However, I need to create an app with a MVC, model-view-controller design pattern. I've seen several posts but all of them involve standard HTML elements. How can I do this with my custom HTML elements (tho not web-components; they don't use a shadow DOM)

ps: i'm not using Jquery but rather standard selectors.

4
  • Show us an example of your custom html output. Commented Feb 5, 2020 at 16:46
  • @TravisActon what do you mean 'output?' well my custom elements include buttons and text fields. do you mean: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>my page</title> ... <script src="file2.js" defer></script> <script src="file1.js" defer></script> </head> <body> <article-link></article-link> <ul id="lists"> <experiment-bucket></experiment-bucket> </ul> <plus-button></plus-button> <br> <submit-button></submit-button> </body> </html> Commented Feb 5, 2020 at 16:53
  • Give us an example of your non-standard html elements and we can show you how to convert it properly to razor syntax. As of now your question is not focused on a single problem and is generic enough that you probably won't get an applicable answer. Commented Feb 5, 2020 at 16:59
  • @TravisActon here's an example: class SubmitAndCreate extends HTMLElement{ constructor(){ super(); } connectedCallback(){ const submitbutton = document.createElement('button'); submitbutton.setAttribute('type','submit'); submitbutton.setAttribute('id','submitButton'); submitbutton.innerHTML = "Submit Test"; submitbutton.addEventListener('click',this.gatherBucketData.bind(this)); this.appendChild(submitbutton); } ... } customElements.define('submit-button', SubmitAndCreate) Commented Feb 5, 2020 at 17:27

1 Answer 1

2

You can use the MVC pattern for Custom Elements just like with standard Javascript.

Define:

  • one object (or a class) for the Controller
  • one for the Model
  • one for the View

There are many ways to define and to interconnect the Model, View and Controller.


Custom Element specific

Adapted to the Custom Element, you can either:

  • define the Custom Element class (extending HTMLElement) as the Controller
  • define the Custom Element class as the View
  • define the the Model, View and Controller inside the Custom Element class
  • define the 3 entities outside the Custom Element class
  • etc.

Example

In the minimalist example implemented below:

  • the Custom Element class defines the Controller
  • the Model is declared in the Controller as a function
  • then the View is declared in the Controller as a function, too

This way the View can access the Model (for data reading) and the Controller directly.

//CONTROLLER
class PersonController extends HTMLElement {
    connectedCallback() {             
        let controller = this 
        let elem = this

        //MODEL
        function PersonModel () {
            //Model API
            this.load = async id => {
                let res = await fetch( `https://reqres.in/api/users/${id}` )
                let json = await res.json()
                Object.assign( this, json.data )
                controller.updateView()
            }
        }                

        let model = new PersonModel

        //VIEW
        function PersonView () {
            elem.innerHTML = `
                Id : <input id=index type=number>
                <div id=card>Loading data
                </div>` 

            let card = elem.querySelector( 'div#card' )
            let index = elem.querySelector( 'input#index' )

            index.onchange = () => controller.init( index.value)               
            
            //View API
            this.update = () => {
                card.innerHTML = `
                    <div>Name : ${model.first_name} ${model.last_name}</div>
                    <div><img src=${model.avatar}></div>`
                index.value = model.id    
            }              
        }

        let view = new PersonView

        //Controller API
        this.init = id => model.load( id )               
        this.updateView = () => view.update() 

        //Init with some data 
        this.init( 4 )
    }
}

customElements.define( 'person-card', PersonController )
person-card { display: inline-block ; background-color: lightblue }
person-card input { width: 50 }
<person-card></person-card>

This example creates a <person-card> element with the MVC pattern that will fetch some data from a REST web service (at reqres.in) and show a person's name, id, and avatar.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.