MVC Intersection Observer structure - javascript

I wonder if someone can assist me with MVC architecture. I took a course in MVC from Udemy and now I have a pet project I'm working on. In a nutshell. I have three JS files: controller, model and view.
I am watching activeHeading2 element and it a user scrolls past it, manipulates classes on two elements.
Anyways, What's happening now is when a user clicks and displays a new section with new activeHeading2 element, Observer still observes old section activeHeading2 in the view even if I tell it to unobserve or even disconnect. I am stuck on this for like a week now, any information or help would be beneficial.
I am not using any frameworks and this is vanilla JS in action:
// CONTROLLER:
constructor(model, view) {
this.view = view;
this.model = model;
// Init here:
this._cycleHeaderFooter();
this._refreshActiveElements();
this.view.bindToTop(this._handleToTop);
this.view.bindNavClick(this._handleNavClick);
this.view.bindObserver(this._handleObserver);
}
_handleNavClick = clicked => {
//View adjustment here
// Unobserve first before resetting ?
this.view.resetNavigation();
this.view.displaySection(clicked);
this._refreshActiveElements();
this.view.observe();
this.view.displayFooter();
this.view.activateNav(clicked);
}
const app = new Controller(new Model(), new View());
export default class View {
constructor() { }
bindObserver(fn){
// DOM, EVENTS,
fn(this.activeHeading2);
}
observe(activeHeading2){
const toggleObserver= (obs, img) =>{
console.log(obs);
if (obs === 'hide') {
this.main__topEl.classList.add('inactive');
this.headerEl.classList.remove('stickyHeader');
}
if (obs === 'show') {
this.main__topEl.classList.remove('inactive');
this.headerEl.classList.add('stickyHeader');
}
if (obs === 'img') {
// console.log(img.dataset.src);
img.src = img.dataset.src;
// Remove blur filter .lazy-img class
img.classList.remove('lazy-img');
}
}
const callback = function (entries, observer) {
const [entry] = entries;
if (entry.target === activeHeading2) {
entry.isIntersecting ? toggleObserver('hide') : toggleObserver('show');
}
}
const options = {
root: null,
threshold: 0,
}
let heading2Obs = new IntersectionObserver(callback, options);
heading2Obs.unobserve(this.activeHeading2);
heading2Obs.observe(this.activeHeading2);
}
}
Not sure why the view is stuck with old values ?

To run code on instantiation of a class, you need a method called contructor not construction.
Also in your code the view parameter passed into the constructor is not the same as this.view, you need to assign it. See code below as an example of what I mean.
class Controller {
constructor(model, view) {
this.view = view;
this.view.bindObserver(this._handleObserver);
}
_handleObserver = (activeHeading2) => {
this.view.observe(activeHeading2);
}
}

Trick to MVC Architecture is knowing how to import each JavaScript class so that it is accessible to other modules. Example:
class View {
}
export default new Class();
--> Then in controller: import view from './view.js'
this will allow controller to see all elements and methods inside that class.

Related

Objects duplicating every component mount. How can I make it run only once ? In react

My object is a independent js file that I created.
componentDidMount() {
const node = ReactDOM.findDOMNode(this);
const widgetBuild = new window.WidgetFormBuilder({
form: $(node).parents('#dynamic_form_wrapper')
});
widgetBuild.initForm();
}
It is a little hard to workout without knowing more about WidgetFormBuilder.
However as good practice I would suggest...
componentDidMount() {
const node = ReactDOM.findDOMNode(this);
// Assign to the class instance
this.widgetBuild = new window.WidgetFormBuilder({
form: $(node).parents('#dynamic_form_wrapper')
});
this.widgetBuild.initForm();
}
componentWillUnmount() {
// Cleanup
// Check if WidgetFormBuilder has a destroy method or something similar.
// See https://reactjs.org/docs/react-component.html#componentwillunmount
this.widgetBuild = null;
}
shouldComponentUpdate() {
// Stop further re-renders, given you're using the DOM directly this could help prevent a few performance issues
// See https://reactjs.org/docs/react-component.html#shouldcomponentupdate
return false;
}
Finally, take a look at the react docs on third party libs.
I already fixed i just added a .destroy() function in my WidgetFormBuilder. :)
WidgetFormBuilder.prototype.destroyBuilder = function () {
const self = this;
const destroyEvents = function () {
$(self.form).unbind();
};
destroyEvents();
return this;
};

React NPM package(Dragula) works in development but not in production

I've built a nice drag'n Drop with React 15 and Dragula 3.7.2 but when i bundle my Application for Production the whole dnd thing doesn't work except i'm able to lift up a single Element but can't find a container to drop it in.
I'm assigning my containers with a reference to my drake instance which i currently create in componentDidMount.
I've assigned multiple EventListener to the drake instance, but the only one which is firing is the 'drag'-eventListener. I console.logged the drake instance in there and saw all my relevant containers correctly assigned
I've also thought that there could be a minification failure with the dragula bundle and so i used the version from the cdn
class ProcessGridDrag extends React.Component {
constructor() {
super();
this.dragContext = null;
this.dragContainers = [];
}
componentDidMount() {
// eslint-disable-next-line no-undef
this.drake = dragula(this.dragContainers, options);
console.log('didMount');
console.log(this.drake.containers);
this.drake.on('drop', this.onDropTile);
this.drake.on('out', this.onOutContainer);
this.drake.on('over', console.log);
this.drake.on('drag', () => {
debugger;
console.log(this.drake);
});
this.drake.on('shadow', console.log);
// Override for touchmove for correct behaviour on iPad
window.addEventListener('touchmove', () => {});
}
componentWillUnmount() {
this.dragContainers = [];
console.log('will Unmount');
this.drake.containers = [];
this.drake.off('drop', this.onDropTile);
this.drake.off('out', this.onOutContainer);
this.dragContext = null;
this.drake.destroy();
}
// This one is passed down to components which should act as a drag container
dragulaDecorator = componentBackingInstance => {
if (
componentBackingInstance &&
this.dragContainers.indexOf(componentBackingInstance) === -1
) {
this.dragContainers.push(componentBackingInstance);
}
};
webpack.config.prod: https://pastebin.com/BLu2hmmv
webpack.config.dev: https://pastebin.com/3wczNisj
I had a Problem with my css. I've overwritten the top-value of the dragged element.
Because of a different LoadOrder in Production this problem only occured there

Page object pattern with protractor

I am trying to creat to page object files with protractor.
My app has the following layout.
and page object files..
navbar_po.js
var NavBar = function() {
// define navbar elements and operations
// .
// .
};
module.exports = NavBar;
subNavbar_po.js
var SubNavBar = function() {
// define subnavbar elements and operations
// .
// .
};
module.exports = SubNavBar;
page1_po.js
var Page1 = function() {
this.navbar = function(){
var navbar = require('./navbar_po.js');
return new navbar();
}
this.subnavbar = function(){
var subnavbar = require('./subNavbar_po.js');
return new subnavbar();
}
// define Page1 particular elements and operations
// .
// .
};
module.exports = Page1;
and I access the navbar elements as follows in test script..
var page1 = new require('./page1_po.js');
page1.navbar.something_method();
page1.subnavbar.something_method();
Is this the best way?
I don't want to define the same navbar elements for each page object file.
Is there any other good way?
Ok, great question, super detailed information too!
🛠 Let's get to it. We'll be using ES6 syntax!
Small structural conventions will make the project easier to maintain and won't need defining the same navbar (or any other) elements for each page object file.
Also, the suggested filename kebab-case style will help keep things recognizable as your project grows :)
navbar_po.js // suggest renaming to nav-bar.pageObject.js
export default class NavBar {
constructor() {
this.homePageButton = element(by.id('home-button'))
// more element locators
}
function clickHomePageButton() {
this.homePageButton.click()
}
// more operations
}
subNavbar_po.js // suggest renaming to sub-nav-bar.pageObject.js
export default class SubNavBar {
constructor() {
this.aboutPageButton = element(by.id('about-button'))
// more element locators
}
function clickAboutPageButton() {
this.aboutPageButton.click()
}
// more operations
}
page1_po.js // suggest renaming to page-one.pageObject.js
import SubNavBar from './sub-nav-bar.pageObject' // the .js at the end can be omitted, it will know it's JS!
import navBar from './nav-bar.pageObject'
export default class pageOne {
constructor() {
this.NavBar = NavBar
this.SubNavBar = SubNavBar
// more element locators
}
function visitHomePageThenAboutPage() {
const navBar = new NavBar()
const subNavBar = new SubNavBar
navBar.clickHomePageButton()
subNavBar.clickAboutPageButton()
}
// more operations
}
your test script
pageOne.spec.js
If any of your elements change, you only ever need to change them in the relevant pageObject file. Nothing else needs changing, not even your test script!
import PageOne from './page-one.pageObject');
describe('navigating', () => {
it('should go to home and about', () => {
const pageOne = new PageOne()
pageOne.visitHomePageThenAboutPage()
// expect statement
}
}
💡 pageObject concept
Imagine that your test script mimics human interaction with your site. And pageObjects are how you abstract away and hide exactly what needs to be done for those user behaviours to interact with your page.
📚 Resources
The following is a great styleguide that helps keep things manageable ✨
https://github.com/CarmenPopoviciu/protractor-styleguide
Also, checkout this (disclaimer: my) curated list on all things awesome for Protractor! Make a pull request if you ever want to add anything!
Good luck testing!
https://github.com/chowdhurian/awesome-protractor
Maybe write a utility for that:
// navbarutil.js
var NavbarUtil = {
create: function(page) {
page.navbar = function() {
return new require('./navbar_po.js')();
}
page.subnavbar = function() {
return new require('./subNavbar_po.js')();
}
}
};
module.exports = NavbarUtil;
And in your page use:
var Page1 = function() {
require('./navbarutil.js').create(this);
// Define other things here...
}
module.exports = Page1;

SPA and Knockout.js AddViewModel breakdown

I am having some issues trying to work out what is going ok with MVC SPA and Knockout.
When you create a new project some files are created for knockout.js as examples, but I am struggling to understand what is going on.
Primarily the issue is with the app.viewmodel.js and the function AddViewModel.
Here is some code which I will attempt to breakdown:
self.addViewModel = function (options) {
var viewItem = {},
navigator;
// Example options
//{
// name: "Home",
// bindingMemberName: "home",
// factory: HomeViewModel
//}
// Add view to AppViewModel.Views enum (for example, app.Views.Home).
self.Views[options.name] = viewItem; // Don't really get this, seems to add a blank object to app.Views.Home
// Add binding member to AppViewModel (for example, app.home);
self[options.bindingMemberName] = ko.computed(function () {
//if (self.view() !== viewItem) {
// console.log(self.view()); // returns {}
// console.log(viewItem); // returns {}
// return null; // should never hit this?
//}
return new options.factory(self, dataModel); // This adds our ViewModel to app.home, app.login, etc
});
// This checks to see if we have defined a navigatorFactory in our viewmodel (AddViewModel)
if (typeof (options.navigatorFactory) !== "undefined") {
navigator = options.navigatorFactory(self, dataModel);
} else {
navigator = function () {
console.log(viewItem);
self.view(viewItem);
};
}
// Add navigation member to AppViewModel (for example, app.NavigateToHome());
self["navigateTo" + options.name] = navigator;
};
ok, so let's start. First of all we declare 2 variables:
var viewItem = {},
navigator;
viewItem is set as a blank object and navigator is undefined.
The first thing we do, is set self.Views[options.name] to our viewItem, so in my understanding, this would mean:
self.Views.Home = {}
If we look at the declaration in app.viewmodel.js self.Views looks like this:
self.Views = {
Loading: {} // Other views are added dynamically by app.addViewModel(...).
};
So in here there is already a view called Loading. So I am confused as to what is actually happening here.
The next bit of code creates a function:
self[options.bindingMemberName] = ko.computed(function () {
return new options.factory(self, dataModel);
});
This is a lot easier to understand. It basically takes our ViewModel and adds it to a function under the name of self.home (or whatever the bindingMemberName of our ViewModel is.
This next piece is what confuses me:
if (typeof (options.navigatorFactory) !== "undefined") {
navigator = options.navigatorFactory(self, dataModel);
} else {
navigator = function () {
console.log(viewItem);
self.view(viewItem);
};
}
// Add navigation member to AppViewModel (for example, app.NavigateToHome());
self["navigateTo" + options.name] = navigator;
If I strip this down, it basically says if we define a navigatorFactory, then the navigator (which is currently undefined!) is equal to our navigatorFactory. That bit is easy.
It's the next bit I don't get.
It says, else, the navigator is a function that returns our self.view(viewItem) (remember that viewItem is just a blank object.
Then we set self["navigateTo" + options.name] = navigator.
So in english, this looks like it is saying, get our blank viewItem, assign it to self.view for every ViewModel we add. Then assign a function returning our self.view(viewItem) to our navigator variable (which is currently undefined) and assign this to our self.naviateToHome() (or whatever).
So to me, that looks like self.navigateToHome(), self.navigateToLogin(), self.navigateToTimbucktoo() would all return the same function with the same self.view.
So, can anyone explain to me what is actually happening?
Update 1
So, I have figured some things out. First things first, the navigator is setting the current view, so basically self.Views looks like this after all the models are added:
self.Views = {
Loading: { },
Home: { },
Login: { }
}
So even though self.view() returns an empty object, it isn't the same as the viewItem because it is stored with the name into self.Views.
So, the navigator is actually applying the viewItem to self.views.
I tested this out by changing the viewItem to this:
var viewItem = { options.name }
and sure enough, self.Views looked liked this:
self.Views = {
Loading: { },
Home: { name: "Home" },
Login: { name: "Login" }
}
so when we set self.view using our navigator, the function is called (app.home for example) and it runs the code to return our factory or null if it isn't the current view.

"Hello World" in MVC Pattern

In an interview for some company, I was asked this question.
What design patterns do you know...then I was told to write simplest "hello world" application based on MVC Design Pattern.
I came up with a JavaScript program
var arr = ["a","b","c","d"]; // this is an array, same as store or model
alert(arr[0]); // this is controller
//and browser alert is a view.
later I was told that alert is a view. The basic concept about MVC I know is any changes in Model are reported to View. And there is a controller in between to call the methods.
Can you correct my approach, or come up with an alternate solution for hello world MVC application. Also explain subtle aspects of MVC.
Thanks.
var M = {}, V = {}, C = {};
M.data = "hello world";
V.render = function (M) { alert(M.data); }
C.handleOnload = function () { V.render(M); }
window.onload = C.handleOnLoad;
Controller (C) listens on some kind of interaction/event stream. In this case it's the page's loading event.
Model (M) is an abstraction of a data source.
View (V) knows how to render data from the Model.
The Controller tells to View to do something with something from the Model.
In this example
the View knows nothing about the Model apart from it implements some interface
the Model knows nothing of the View and the Controller
the Controller knows about both the Model and the View and tells the View to go do something with the data from the Model.
Note the above example is a severe simplification for demonstrating purposes. For real "hello world" examples in the JS MVC world go take a look at todoMVC
Better Example
var M = {}, V = {}, C = {};
/* Model View Controller Pattern with Form Example */
/* Controller Handles the Events */
M = {
data: {
userName : "Dummy Guy",
userNumber : "000000000"
},
setData : function(d){
this.data.userName = d.userName;
this.data.userNumber = d.userNumber;
},
getData : function(){
return data;
}
}
V = {
userName : document.querySelector("#inputUserName"),
userNumber : document.querySelector("#inputUserNumber"),
update: function(M){
this.userName.value = M.data.userName;
this.userNumber.value = M.data.userNumber;
}
}
C = {
model: M,
view: V,
handler: function(){
this.view.update(this.model);
}
}
document.querySelector(".submitBtn").addEventListener("click", function(){
C.handler.call(C);
});
/* Model Handles the Data */
/* View Handles the Display */
MVC Architecture
I have written an article about MVC architecture. Here is only some code present,hope anyone finds it helpful.
//Modal
var modal = { data: "This is data"};
//View
var view = { display : function () {
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
}
};
//Controller
var controller = ( function () {
view.display();
})();
From the above example just understand that there are three different units in this design where each has a specific job to perform. Let's build the MVC design from the above infra structure .There can be more than one view and Observer, here only another view is created first.
// Modal
var modal = { data: "This is data"};
// View
var slashView = { display : function () {
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
}
};
var starView = { display : function () {
console.log ("****************************");
console.log ( modal.data);
console.log ("****************************");
}
};
// Controller
var controller = ( function () {
slashView.display();
starView.display();
})();
What is understood here is that the modal must not be dependent upon either the view or viewers or the operations performed on the data. The data modal can stand alone but the view and controller are required because one needs to show the data and the other needs to manipulate it. Thus view and controller are created because of the modal and not the other way round.
//Modal
var modal = {
data : ["JS in object based language"," JS implements prototypal inheritance"]
};
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
console.log(this.modal.data[0]);
console.log("***********************************");
};
}
function Controller(v){
this.view = v;
this.informView = function(){
// update the modal
this.view.display();
};
}
// Test
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.informView();
From the above it can be seen that there has been a link established between view and the controller. And this is one of the requirement of MVC pattern. To demonstrate the change in the modal let's change the program and observe that change in the state of modal is done independently and reflects in view.
//Modal
function Modal(){
this.state = 0;
this.data = ["JS is object based language","JS implements prototypal inheritance"];
//
this.getState = function (){
return this.state;
};
this.changeState = function (value) {
this.state = value;
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
console.log(this.modal.data[modal.getState()]);
console.log("***********************************");
};
}
//controller is created with the view
function Controller(v){
this.view = v;
this.updateView = function(){
// update the view
this.view.display();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.updateView();
// change the state of the modal
modal.changeState(1);
controller.updateView();
When the state of the modal is changed the controller has sent the message to the view to update itself. It is fine, but still one main concept is left to be implemented and that is the observer or controller needs to be identified by the modal . In order to see this happening, there has to be a link between modal and the controller so that any number of controller can show the interest in the modal, this is considered as registering the observer to the modal. This relation ship is implemented using the concept that observer does not exist in the air. Its existence come because of having interest in the modal thus when it is created it has to be created using the modal that it needs to show interest or in other words it has an access to the modal. Let's look at the example below and see how this MVC design pattern is achieved simply and elegantly using JavaScript.
function Modal(){
var stateChanged = false;
var state = 0;
var listeners = [];
var data = ["JS is object based language","JS implements prototypal inheritance"];
// To access the data
this.getData = function(){
return data;
};
// To get the current state
this.getState = function (){
return state;
};
// For simplicity sake we have added this helper function here to show
// what happens when the state of the data is changed
this.changeState = function (value) {
state = value;
stateChanged = true;
notifyAllObservers();
};
// All interested parties get notified of change
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
};
// All interested parties are stored in an array of list
this.addObserver = function (listener){
listeners.push(listener);
};
}
// View class, View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
console.log("***********************************");
};
}
// Controller or Observer class has access to both modal and a view
function Controller(m,v){
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// update view
this.updateView = function(){
this.view.display();
};
// Receives notification from the modal
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
modal.changeState(1);
modal.changeState(0);
modal.changeState(1);
modal.changeState(0);
From the above it can be seen that the observer has register itself using modal addObsever function and establishes a link to the modal. Once all instances are created. Modal state was changed manually to show the effect in the view. Typically in GUI environment, the change is usually done either with a user pressing any button or from any other external input. We can simulate the external input from the random generator and observe the effect. Here in the example below, some more elements are added in the data to show the effect clearly.
function Modal(){
var stateChanged = false;
var state = 0;
var listeners = [];
var data = [
"JS is object based language","JS implements prototypal inheritance",
"JS has many functional language features", "JS is loosely typed language",
"JS still dominates the Web", "JS is getting matured ","JS shares code
through prototypal inheritance","JS has many useful libraries like JQuery",
"JS is now known as ECMAScript","JS is said to rule the future of Web for
many years"];
//
this.getData = function(){
return data;
};
//
this.getState = function (){
return state;
};
this.changeState = function (value) {
state = value;
stateChanged = true;
notifyAllObservers();
};
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
}
this.addObserver = function (listner){
listeners.push(listner);
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
};
//Adding external simulation of user sending input
this.pressButton = function(){
var seed = 10;
var number = Math.round(Math.random() * seed) ;
// change the state of modal
this.modal.changeState(number);
};
}
// Controller class needs modal and view to communicate
function Controller(m,v){
this.view = v;
//console.log(this.view.display);
this.modal = m;
this.modal.addObserver(this);
this.updateView = function(){
// update the view
//console.log(this.view);
this.view.display();
};
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
for ( var i = 0 ; i < 10; i++){
consoleView.pressButton();
}
The above example demonstrates the use of MVC frame work where a modal is kept independent of the view and and the controller. The modal representing the data is responsible of notifying all the interested parties that has shown the interest and registered themselves with the modal. As soon as any change happens notification is send to the parties and action is left upon them. The example below is slightly different from the above where only newly added data is shown by the observer.
function Modal(){
var stateChanged = false;
var listeners = [];
var data = ["JS is object based language"];
// To retrieve the data
this.getData = function(){
return data;
};
// To change the data by any action
this.modifyData = function (string) {
( data.length === 1 )? data.push(string): data.unshift(string);
stateChanged = true;
notifyAllObservers();
};
// Notifies all observers
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
}
// Requires to register all observers
this.addObserver = function (listener){
listeners.push(listener);
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[0]);
console.log("****************************************************");
};
//Adding external simulation of user sending input
this.pressButton = function(string){
// change the state of modal
this.modal.modifyData(string);
};
}
// View class
function Controller(m,v){
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// Updates the view
this.updateView = function(){
this.view.display();
};
// When notifies by the modal send the request of update
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
consoleView.pressButton();
consoleView.pressButton("JS dominates the web world");
consoleView.pressButton("JQuery is a useful library of JS");
The last thing which one may like to add is to delete the observer when not needed.This can be done through adding a method called removeObserver(object) in the modal calls. The above MVC design pattern can be more refined by using subcalssing and having common function present in the top class making the design as simple as possible but it is left on some other article. Hope it helps.
MVC is a design pattern that should be used to structure your application. MVC stands for Model, View, Control. It basically sais that you should separate your business-logic (Model) from your User Interface (View) and your Control-Logic.
For example:
You have a user class, that loads users from the database, can save em. This is your model.
You have a Controller that uses the User class to log a user in.
After the controller is done, it displays a Template containing the Text "Welcome $username".
Also, the Model should not know about the View and the Controller, the View should not know about the Controller, whereas the Controller knows about the Model and the View.
Wikipedia on MVC: http://de.wikipedia.org/wiki/Model_View_Controller
I think you're kind of missing the point here.
MVC is a pattern you'd use for designing an application. I think at the minimum you'd expect to be able to change the model, and see the change reflected in the view.
You'd typically have an object to represent the model, a different object to represent the "view" (which would probably mediate between the model and the HTML objects that you're using as the view) and a controller, which would take inputs from your HTML objects and update the model.
So you change an edit field, the edit field tells the controller, the controller updates the model, the model fires events that the controller uses to update any other view components that depend on this data.
It'd be a few more lines to implement a "hello world" version, but I think this is what I'd be looking for from an interview question like this.
So I made a simple example MVC with data output at console.log().
let model = {
data: {
text: "Hello World",
},
};
let view = {
init: function () {
this.render();
},
render: function () {
console.log(model.data.text);
},
};
let controller = {
init: function () {
view.init();
},
};
controller.init();

Categories

Resources