Carduelis
@Carduelis
Web-developer, front-end, js, less

Как рендерить во view, дожидаясь загрузки данных по ajax в model?

app.init = function() {
     this.model.load('tabs');
     this.view.render('tabs');
}
app.model = {
    load : function(entity) {
        $.getJSON( entity+'.json', json => this[entity] = json);
    }
}

app.view = {
    render: function(entity) {
         jsonToHmtl(app.model[entity]);
    }
}

function jsonToHtml(json) {
    // рендер lodash
}


Как сказать рендеру, что можно рендерить полученный json, учитывая mvc-паттерн? Или я чего-то не понимаю в этой жизни о_о
  • Вопрос задан
  • 237 просмотров
Решения вопроса 1
@bromzh
Drugs-driven development
Да, ты не понимаешь асинхронность в JS и MVC.
Нужно рендерить после получения данных. Например, можно вызывать функцию render в колбеке getJSON. Ещё лучше вернуть промис и вызывать рендрер в колбеке then.
Но это всё равно ни разу не MVC.
А не могли бы вы помочь, как это делать в парадигме MVC?

Ну тут всё не так просто. Если ты хочешь использовать MVC-фреймворки, то смотри, как там всё организовано у них. Примеры реализации простого MVC приложения см. тут.

Если же забыть про тонны готовых MVC, то можно сделать всё самому. Тут важно понимать, что:
1) Модель - это вся бизнес-логика. И она не знает ни про View, ни про Controller. В классическом MVC модель оповещает всех подписчиков об изменении своих данных.
2) Вид (view) должен знать про модель, но не про контроллер. В классическом MVC вид подписывается на события модели и при возникновении события он перерисовывается.
3) Контроллер знает про вид и про модель. В классическом MVC он связывается с каким-то видом и при определённом действии пользователя что-то делает. Например, он может вызывать какие-то методы у модели. А может и изменять состояния вида (хотя так лучше не делать в идеале, так как повысится связность системы, что плохо).

Итак, вот тебе пример. Немного корявый, но суть должна быть ясна.

Сперва посмотри в script.js.

Там есть класс-модель. Чтобы связать Model и View обычно применяют паттерн проектирования observer. У модели есть список слушателей. Каждый слушатель - просто функция-коллбек, которая принимает 1 аргумент - данные этой модели. При этом, сама модель не знает вообще ни про какой View. Слушатели в модели - это просто массив функций, которые будут вызваны.
В модели есть метод для добавления слушателя и для оповещения всех слушателей о получении новых данных. Метод getData эмулирует асинхронный запрос данных. В этом методе создаётся промис. Если данные найдены, то вызывается метод оповещения всех слушателей и промис резолвится. Если данные не найдены, то промис реджектится.

Далее, небольшая иерархия view-классов.
Класс BaseView. Там есть конструктор, который связывает экземпляр класса с DOM-элементом; метод subscribe, который добавляет к модели простого слушателя. Слушатель вызывает метод render с данными, которые нужно отрендерить и записывает полученный из метода render HTML в элемент. В самом классе BaseView метод render выплюнет ошибку, так что нужно написать несколько классов-наследников.
Класс ListView наследуется от BaseView и просто добавляет вспомогательный метод, который просто обрамляет каждый объект из массива с данными в элемент .
Ну и наконец, есть 2 класса, которые непосредственно реализуют метод render.
В итоге, класс UlView генерирует из массива данных ненумерованный список, а класс OlView - нумерованный.

Теперь в самом index.html можно увидеть всё в деле. Создаём модель и 2 view. Каждый view инициализируем соответствующим div-элементом. Далее,
При нажатии на кнопку вызывается коллбек, который вызывает метод модели. Если модель смогла получить данные, то подписанные на эту модель вьюхи рендерят эти данные, причём каждый view делает это по-разному. Как тут можно заметить, модель вообще никак не зависит от view. Можно связывать сколько угодно вьюх без какого-либо изменения самой модели.

В общем, как-то так. Это конечно очень простой и довольно корявый пример (например, тут нет возможности связать контроллер и сам view, это уж сам изучи), так что не следует этот код использовать где-то в своих проектах.
Ну и почитай ещё про MVC, посмотри реализацию TodoMVC на разных фреймворках.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы