Где поместить взаимодействие DOM в масштабируемую архитектуру JavaScript - PullRequest
5 голосов
/ 19 декабря 2011

В настоящий момент я немного сбит с толку относительно того, как создать более поддерживаемую архитектуру JavaScript.Возможно, я не в курсе, но я бы сказал, что почти 50% моего кода использует DOM, поэтому использую мою базовую библиотеку (jQuery).

Я проверил [1] архитектуру масштабируемого приложения Николаса Закасаdesign: http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture и [2] шаблоны Addy Osmani для крупномасштабной архитектуры приложений JavaScript http://addyosmani.com/largescalejavascript/.

У меня есть одностраничный стиль приложения, с большим количеством контента, извлекаемого черезЭлементы ajax и DOM добавляются динамически.Мой главный вопрос: как разделить код на небольшие блоки многократного использования, если я использую jQuery (или любую другую базовую библиотеку) для манипулирования DOM.

Давайте просто выберем модуль списка задач, например,Я понимаю, что модуль может выглядеть так:

var TaskList = function() {
  addTask = function() {
    ...
  };

  removeTask = function() {
    ...
  };

  return {
    addTask: addTask,
    removeTask: removeTask
  }
}();

Где должна быть записана регистрация событий элементов DOM, ajax-вызов для сохранения, загрузки или удаления задачи, добавление новой задачи в элемент DOMи т. д.

У меня нет проблем с фиксацией jQuery на модуле в качестве зависимости, но если есть лучший способ, я думаю, что я пропустил его из двух вышеупомянутых ресурсов, и я хотел бы узнать это.

Я просто хочу иметь более элегантный способ поддержания растущего JavaScript, потому что я устал от спагетти;)

Спасибо за ваше время!

Ответы [ 3 ]

0 голосов
/ 20 декабря 2011

Вы можете использовать Backbone.js или вы можете исследовать CQRS (и связанные шаблоны) для более нестандартного, сложного и развязанного решения. Все зависит от сложности вашего приложения (и потенциального будущего роста).

Вы также можете проверить некоторые из этих сообщений . Есть несколько хороших, которые нацелены на ваш вопрос в конкретных примерах;)

0 голосов
/ 09 августа 2017

Разделяйте бизнес-логику и отображайте логику отдельно

Однако это относится не только к DOM.Многие API, как в браузере, так и в Node, разработаны для запуска и прослушивания событий или ожидания завершения других типов асинхронной работы.Практическое правило заключается в том, что если вы пишете много анонимных функций обратного вызова, ваш код может быть нелегко протестировать.

// hard to test
$('button').on('click', () => {
    $.getJSON('/path/to/data')
        .then(data => {
            $('#my-list').html('results: ' + data.join(', '));
        });
});

// testable; we can directly run fetchThings to see if it
// makes an AJAX request without having to trigger DOM
// events, and we can run showThings directly to see that it
// displays data in the DOM without doing an AJAX request
$('button').on('click', () => fetchThings(showThings));

function fetchThings(callback) {
    $.getJSON('/path/to/data').then(callback);
}

function showThings(data) {
    $('#my-list').html('results: ' + data.join(', '));
}

Использование обратных вызовов или обещаний с асинхронным кодом

Наиболее распространенным способом решения этой проблемы является передача функции обратного вызова в качестве параметра функции, которая выполняется асинхронно.В ваших модульных тестах вы можете выполнить свои утверждения в обратном вызове, который вы проходите.

// hard to test; we don't know how long the AJAX request will run
function fetchData() {
    $.ajax({ url: '/path/to/data' });
}

// testable; we can pass a callback and run assertions inside it
function fetchDataWithCallback(callback) {
    $.ajax({
        url: '/path/to/data',
        success: callback,
    });
}

// also testable; we can run assertions when the returned Promise resolves
function fetchDataWithPromise() {
    return $.ajax({ url: '/path/to/data' });
}

Вот подробности

0 голосов
/ 20 декабря 2011

Поскольку вы собираетесь разрабатывать одностраничное приложение, у вас будет много визуальных модулей, которые будут отображаться на текущем этапе, а затем они будут заменены другими.

Вы можете следовать шаблону MVC (Model-Controller-View), где каждый визуальный элемент представляет собой отдельную сущность со своим собственным кодом для манипулирования DOM и бизнес-логикой, хранящейся в отдельных классах.

Один из способов будет:

<html>
  <head>
   ....
  </head>
  <body>
    <div id="content"> 
    <!--The main container view that can handle the replacement of smaller views -->
      <div id="toolbar"_container">
        <!-- container for menu bar or tool bar that can also has its contained 
             sub-views replaced -->
      </div>
      <div id="main_content_container">
        ....
      </div>
      <div id="properties_panel">
       .....
      </div>
    </div>      
  </body>
</html>

Основной контейнер может содержать все меньшие контейнеры, причем каждый из них имеет свой контроллер представления, который имеет собственный код манипуляции DOM (что также дает возможность динамической загрузки по требованию и, таким образом, сокращает время инициализации загрузки ).

У каждого представления может быть модуль пары, который будет выполнять «действия» и который будет взаимодействовать с третьим модулем (необязательно), который будет заботиться о вводе-выводе с базами данных, сокетами, файлами и т. Д.

Надеюсь, это помогло!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...