Правильная реализация MVC на ES6?

212
20 апреля 2018, 15:44

Добрый день! Не могу понять, как правильно реализовать MVC паттерн, вот пример кода:

class View {
    exampleMethod() {
        var btn = document.querySelector('.btn');
       btnClose.addEventListener('click', function () {
      console.log(this.arr);
});
    }
}
class Model {
    constructor() {
        this.arr = ['1'];
    }
}
class Controller {
    constructor(view,model) {
        this.view = view
        this.model = model
    }
}
const myView = new View()
const myModel = new Model()
const myController = new Controller(myView,myModel)

Я не понимаю, как правильно связать view, что бы при клике отображалось значение в module ? Надеюсь доступно объяснил, спасибо!

Answer 1

Не знаю как в javascript это реализовать, а на c# это выглядело бы примерно так:

class Program
{
    class View
    {
        public Controller Controller { get; set; }
        public void show()
        {
            Console.WriteLine(Controller.Model.Value);
        }
    }
    class Model
    {
        public string Value { get; set; }
        public Model()
        {
            Value = "1";
        }
    }
    class Controller
    {
        public View View { get; set; }
        public Model Model { get; set; }
        public Controller(View view, Model model)
        {
            View = view;
            Model = model;
            View.Controller = this;
        }
    }
    static void Main(string[] args)
    {
        Controller myController = new Controller(new View(), new Model());
        myController.View.show();
        myController.Model.Value = "2";
        myController.View.show();
        Console.ReadLine();
    }
}

Основная идея такая:

Model - содержит структуру данных.

Controller - Может играться с заполнением данных и вызовом вывода этих данных в интерфейс для пользователя.

View - содержит методы, которые отображают те данные, которые были заполнены в структуре Model контроллером.

При этом:

Model - ничего не знает о том, как данные будут отображаться. Возможно, в этих классах также реализация по заполнению и обработке данных (не только в контроллере)

View - ничего не знает о том, откуда получаются и как данные обрабатываются. Знает только о том, куда и как эти данные отобразить.

Controller - Ничего не знает об отображении данных. В принципе, может вообще ничего не знать о том, как данные заполняются и обрабатываются (если логика перенесена в Model). Знает только что данные хранятся в Model и выводятся через View.

Answer 2

Я не понимаю как правильно связать view, что бы при клике отображалось значение в module ?

В данном случае, логично связать через контроллер. Хотя можно и напрямую (например, передавая конструктору представления ссылку на модель). Второй вариант удобен когда представление само периодически выводит данные, без участия пользователя.

Проблема вашего кода в том что view пытается получить arr как свое свойство, хотя это свойство model.

Если развивать ваш пример, я бы сделал так (связь через контроллер, так как данные выводятся по нажатию на кнопку):

class View { 
  log(data) { 
    console.clear();  
    console.log(data.join(', ') || 'Нет данных'); 
  } 
  reportOk(el) { 
    el.style.animation = 'green-bg 0.5s ease-in reverse';  
    setTimeout(() => { 
      el.style.animation = null;  
    }, 500);  
  } 
};  
 
class Model { 
  constructor()   { this.arr = []; } 
  get data()      { return this.arr; } 
  set data(value) { this.arr = value.slice(); } 
  sort() { this.arr.sort((a, b) => a - b); } 
};  
 
class Controller { 
  constructor(view, model) { 
    this.view  = view  || new View();  
    this.model = model || new Model();  
  } 
  eventHandler(e) { 
    switch (e.target.getAttribute('mvc-do')) { 
      case 'log':  
        this.view.log(this.model.data);  
        break;  
      case 'add':  
        let newData = [],  
            len = e.target.getAttribute('mvc-len') || 5;  
        for (let i = 0; i < +len; i++) 
          newData[i] = Math.floor(Math.random() * 100);  
        this.model.data = newData;  
        newData.splice(0, newData.length);  
        break;  
      case 'sort':  
        this.model.data.sort();  
        break;  
      default:  
        return;  
    } 
    this.view.reportOk(e.target);  
  } 
  connectElements(selector, event) { 
    let els = document.querySelectorAll(selector); 
    for (let el of els) 
      el.addEventListener(event, e => this.eventHandler(e));  
  } 
};  
 
 
const myView  = new View(),  
      myModel = new Model(),  
      myController = new Controller(myView, myModel);  
//const myController = new Controller();  
myController.connectElements('button', 'click'); 
button { 
  margin: 10px 5px; padding: 4px 12px;  
  font: 18px sans-serif;  
} 
 
@keyframes green-bg { to { background-color: #7e7; } }
<button mvc-do="add" mvc-len="12">Новые данные</button> 
<button mvc-do="sort">Отсортировать</button> 
<button mvc-do="log">Вывести в консоль</button>

Данный пример кода не претендует на соответствие каким-либо канонам и/или шаблонам.

Answer 3

MVC это паттерн в котом view выступает логикой отображения, model основной логикой, а все это связывает бизнес логика controller, в вашем примере эта далеко не всегда простая реализация паттерна, вообще не нужна. Вам могу подсказать посмотреть курс от LoftBlog и изучить MVC фреймворки вроде VueJS.

READ ALSO
Как создать таймер для пользователя?

Как создать таймер для пользователя?

У меня бот для вкМне нужно что бы при вводе команды test бот ответил пользователю "Работаю"

147
Как поставить на img эффект tooltip . wordpress?

Как поставить на img эффект tooltip . wordpress?

Как поставить эффект tooltip js на img , проект на wordpress

198
Как сделать таблицу рекордов в игре на Javascript с использованием localstorage?

Как сделать таблицу рекордов в игре на Javascript с использованием localstorage?

В общем, суть в следующемВ начале игры заполняются данные формы, типа Имя, Фамилия, и отправляются в localstorage

638
Ошибка addEventListener &#39;null&#39;

Ошибка addEventListener 'null'

Есть событие которое выполняется при изменении содержимых тегов iteminfo0 и iteminfo1

216