Помогите учиться на javascript в pivotaltracker, ища разбивку на высоком уровне - PullRequest
8 голосов
/ 16 июля 2011

Мои навыки работы с javascript довольно просты, я могу работать с jquery и т. Д., Но когда дело доходит до создания сайта, такого как pivotaltracker, я не знаю, с чего начать!

Надеялся, что кто-то может помочь сломать свою архитектуру javascript и объяснить на высоком уровне, как они пошли на разработку своего js frameowork для создания дизайна, подобного gmail, где он основан исключительно на javascript (по крайней мере, я так думаю).

Такие вещи, как:

  1. в плане компоновки, есть ли один контейнер div, который загружает разные панели?
  2. Сохраняет ли он копию всех историй в браузере и использует шаблоны javascript для построения HTML?
  3. как устроены различные объекты
  4. Я думаю, что это главное, как связаны события, это глобальное событие, которое вспыхивает?

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

Ответы [ 4 ]

7 голосов
/ 28 июля 2011

Я думаю, что ваш вопрос больше касается понимания паттернов MVC ( модель-представление-контроллер ) в javascript.Я думаю, вам следует обновить свой вопрос, чтобы отразить это.

Что-то вроде «Помогите понять шаблоны MVC в javascript».

Трудно составить представление о том, как это выглядит в javscript, не предоставивдемонстрационный пример использования с примерами и подробным описанием кода.Я знаю, что по сути это то, о чем вы просили, но я думаю, что это выходит за рамки StackOverflow.

Шаблоны MVC довольно знакомы и широко используются, например, в серверных средах.

  • В PHP есть CodeIgnighter
  • В Ruby есть Rails
  • В Python есть Django
  • В Java есть Spring
  • Плюс много, много других вариантов для каждого языка.

Шаблон MVC тесно связан с концепцией ООП ( объектно-ориентированное программирование ).Хотя для языка не принципиально быть объектно-ориентированным, чтобы следовать шаблону MVC.Многие фреймворки MVC, как правило, создаются в соответствии с методологиями ООП, насколько позволяет язык.

Это одна из причин, по которой я считаю, что концепция MVC менее распространена в фронт-энде.В течение долгого времени Javascript был довольно неправильно понят как язык.В результате только недавно люди применили принципы ООП в javscript.

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

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

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

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

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

  2. Чем больше времени выпотратить работу в рамках, тем более знакомым вы станете с API.Таким образом, это ускоряет время разработки.

  3. Общая структура и API облегчают вам и другим пользователям поддержку кодовой базы.

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

Для начала я не думаю, что термин MVC находится в правильном порядкечтобы помочь визуализировать течение внутренних процессов.Является ли это намеренным или нет, я не знаю, я предполагаю, что разные люди воспринимают вещи по-разному, но мне кажется, что MVC проще сказать и звучит лучше.

Я предпочитаю думать об этом как CVM.

Ключевым моментом в инфраструктуре MVC является разделение логики.

КОНТРОЛЛЕР >> Контроллер - это функциональная часть приложения, каждый контроллер имеет определенный аспект взаимодействия с пользователем.Затем он управляет обработкой этого взаимодействия, передавая изменения в модели и представления, основываясь на полученных им входных данных.

МОДЕЛЬ >> Модель - это все о данных.У него только одна работа - моделирование данных.Таким образом, Модель обычно принимает данные и проверяет или изменяет свое представление.Модель также заботится о CRUD-операциях (создание, чтение, обновление, удаление).Обычно у вас есть отдельная модель для разных типов данных, проходящих через ваше приложение.например, Пользователи, Комментарии, Сообщения.

ПРОСМОТР >> Вид - это визуальное представление операции.Он берет данные из модели и генерирует визуальный вывод.В то время как представление генерирует визуальный вывод, обычно представление само по себе не выполняет его рендеринг.Он просто возвращает визуальное представление в контроллер для рендеринга.Представления не связаны с целыми страницами, каждое представление представляет отдельный визуальный аспект приложения, например, диалоговое окно входа, новый комментарий и т. Д.

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

В серверной среде MVC взаимодействие с пользователем, на которое они отвечают, обычно является запросом страницы.Поэтому контроллеры слушают запросы, поступающие от клиента.Они используют параметры URL и запроса, чтобы определить, какой контроллер отвечает за обработку этого запроса.

e.g. http://myapp.com/users/ >> user Controller

Затем контроллер может использовать любую последующую часть URL, чтобы определить, какие модели и представления следует использовать дляответить.

e.g. http://myapp.com/users/new/ >>  user Controller renders the newUser View

Среды MVC на стороне сервера используют фрагменты URL для ответа на взаимодействие с пользователем, поскольку они не имеют прямого доступа к взаимодействию с пользователем (например, сервер не может реагировать непосредственно на щелчок мыши),Так что серверные приложения работают не по выбору, а по принуждению.

В Javscript, тем не менее, у нас есть такая роскошь.Мы можем добавить обработчики событий в части интерфейса и реагировать непосредственно на взаимодействие с пользователем.Эта модель знакома практически каждому пользователю JavaScript.

Например (с использованием jQuery)

// Create and event handler
$('.myButton').bind('click', function(event){
    // Do some work when this event is fired.
});

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

Например,

$('myButton').bind('click', function(event){
    var self = $(this);
    event.preventDefault();

    $.ajax({
        url: self.attr('href'),
        context: self.parents('.ResponseContainer'),
        success: function(data){
            self.addClass('.workDone');
            for( key in data ){
                $(this).append('<li>'+data[key]+'</li>')
            };
        }   
    }); 
});

Поэтому способность JavaScripts напрямую взаимодействовать с взаимодействием фактически становится недостатком.Наличие глобального объекта, такого как URL-адрес для ответа, значительно упрощает обработку и концептуальное моделирование и разделение частей приложения.

Теоретически вы можете создать собственный глобальный объект для хранения состояния приложения и отслеживания его состояния.изменения в ваших контроллерах.Однако для большинства приложений это ненужное занятие, оказывается, что объект URL является простым и высокоэффективным для этой операции.Поскольку в своих фрагментах URL-адрес содержит форму состояния, пользователи могут переходить прямо к определенным частям вашего приложения.Если вы реализуете свой собственный объект для выполнения работы с URL, приложение не будет иметь никаких сведений о состоянии до его загрузки.Любое состояние во время выполнения также будет потеряно, как только страница закроется.Таким образом, URL обеспечивает превосходный механизм для постоянного и передаваемого состояния (так как URL может использоваться совместно).

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

Это явно не то, что мы хотим, чтобы произошло.Таким образом, чтобы предотвратить это, фреймворки MVC используют несколько методов, чтобы изменить поведение браузера по умолчанию.Первый механизм состоит в том, чтобы запретить использование по умолчанию для всех щелчков по ссылкам.

например

$('a').bind('click', function(event){
    event.preventDefault(); 
});

// This prevents any link clicks from firing the browsers default action
// of making a request to the server and reloading the page.

Чтобы изменить URL, мы должны обновить объект window.location, чтобы он указывал на URL, содержащийся в атрибуте links href.Однако простое изменение window.location все равно приведет к перезагрузке страницы.Чтобы преодолеть это, мы фактически изменили URL, чтобы использовать фрагменты хеша, например http://myapp.com/#/users. Когда браузер видит хэш в URL, он не перезагружает страницу.Исторически хеш использовался для перехода к разделу контента на существующей странице.

Обновления хэша также попадают в историю просмотров, что позволяет вам перемещаться с помощью кнопок браузера «назад» и «вперед».

например,

$('a').bind('click', function(event){
    event.preventDefault();
    var el = $(event.currentTarget);
    window.location.hash = el.attr('href');
});

// A real use case would be much more complex than this.
// This code assumes you have a link structured like 
// <a href="/new/user">Sign up</a>

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

Чтобы позволить контроллерам отвечать на правильный URL-адрес (также называемый маршрутами), обычно используются соглашения об именах объектов или методов.

Например,

//Create your controller to listen to '/user' fragments
var users = new Controller('/users');

// function to run on '/user' fragment changes
users.On = function(reqParams){
    // do some work to respond to http://myapp.com/#/users; 
};



// create a Controller as a method of users, to respond to '/users/new'
users.new = new Controller('/new');

// function to run on '/user/new' fragment changes
users.new.On = function(reqParams){
    // do some work to respond to http://myapp.com/#/users/new          
};

Я не буду вдаваться в подробности, инфраструктуры MVC предоставляют различные способы реализации и структурирования вашего приложения.Кроме того, поскольку JavaScript действительно способен напрямую реагировать на взаимодействие с пользователем, эту мощь не следует полностью игнорировать.Поэтому в некоторых JavaScript MVC-структурах они слегка портят чистую концепцию MVC, чтобы обеспечить более глубокое управление взаимодействием.

Я наткнулся на это видео-руководство Бена Наделя, исследующее концепцию MVC в одностраничных веб-приложениях.Это чрезвычайно подробный обзор структуры приложения.А также дает несколько замечательных советов по созданию JavaScript.

Некоторые Javascript MVC Framework

Обзор нескольких структур, упомянутых выше.

И не забудьте прочитать красноречивый JavaScript, если вы этого еще не сделали

Надеюсь, вам хватит информации, чтобы начать.

2 голосов
/ 26 июля 2011

Пользовательский интерфейс Pivotal Tracker (и js) очень похож на Google Wave (Wave in the Box) Спецификация протокола Wave Поэтому я думаю, что он имеет следующую архитектуру.

Главная страница состоит из загрузчика html и js. HTML прост - просто div без содержимого. Загрузчик запускается при загрузке страницы, просто так

$(document).ready(function(){
        $("#main_holder").buildPage("home"); // jquery example
});

Эта функция запускает 2 задачи:

  • загрузка данных (например, через AJAX)
  • UI сборки с загруженными данными

Загрузка данных - чистая операция. Создание пользовательского интерфейса является более сложным. Пользовательский интерфейс строится с простыми элементами управления - виджеты (или какие-то виджеты). У каждого виджета есть свой код для сборки и инициализации обработчиков событий. Каждый загруженный виджет регистрируется в загрузчике (или посреднике), поэтому он может получить доступ к данным других виджетов через загрузчик.

Для построения html для каждого виджета используются шаблоны (своего рода шаблоны JSP). Пример шаблона

    <li class="task_<%=id%> <%= readOnly ? 'readonly' : '' %>">
  <% if (!readOnly) { %>
    <input type="checkbox" name="task[complete_<%=id%>]" value="1" <%= complete ? "checked='checked'" : "" %>/>
    <div style="display:none"><textarea class="autoresize expand17-10000" name="task[description_<%=id%>]"><%= description %></textarea></div>
  <% } else { %>
    <div><%= position %>.</div>
  <% } %>
  <label <%= complete ? "class='completed'" : "" %>><%= Element.formatText(description) %></label>
  <% if (!readOnly) { %>
    <ul class="actions">
      <li class="edit"><a href="#" title="Edit Task"><img src="<%= edit_img_src %>" /></a></li>
      <li class="delete"><a href="#" title="Delete Task"><img src="<%= delete_img_src %>" /></a></li>
    </ul>
  <% } %>
</li>

Шаблон компилируется механизмом шаблонов и становится чистым HTML-кодом.

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

Различные объекты, спроектированные как ассоциативные массивы. Как

    org.pivotal.model.vo.VariousObjectVO = new Class({
      /**
       *
       * @param {Long} id
       * @param {String} name
       * @param {Map<String, String>} fields
       * 
       */
       initialize: function(){

       },
       id: null,
       name: "",
       fields: {}
    });

Таким образом, вы можете вести любое количество полей с любым количеством значений.

Надеюсь, это поможет.

С уважением, Сергей

1 голос
/ 26 июля 2011

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

Из того, что я вижу, он построен с различными "виджетами",Позвольте мне выбрать страницу панели инструментов и показать, как ее проектировать.

1.Макет

Как это выглядит, они имеют 3 колонки макета.Вы можете выбрать фиксированную компоновку или флюидную компоновку в соответствии с вашими потребностями.

Если вы посмотрите на основную точку, у них есть флюидная компоновка для приборной панели в качествеизменение размеров панелей при изменении размера браузера.

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

2. Клиентские шаблоны

Идея состоит в том, что вы получаете данные через вызовы Ajax, а затем используете механизм шаблонов на стороне клиента, чтобы связать ваши данные с разметкой шаблона для созданияжелаемая выходная разметка.

Псевдокод для загрузки виджета:

 1. Getdata  // $.ajax() or any other way
 2. Bind data to template (using underscore templates or other templating engines)
 3. Append the HTML to the panels

По своему опыту, я нашел Underscore.js шаблоны чрезвычайно простыми и быстрыми (Я рекомендую их поверх шаблонов jQuery)

Шаблон HTML и соответствующий ему скрипт будут составлять widget.

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

3.Объектный дизайн

Краткий ответ - основывайте его на своей модели представления.JSON-объект, который вы отправляете клиенту, должен быть подмножеством вашей модели представления, содержащей только релевантных данных, необходимых для рисования виджетов и включения взаимодействия (ключи, идентификаторы и т. Д.) Через события.

4.Управление событиями

Для управления событиями я бы сказал следующее:

  • каждый виджет является автономным.В том смысле, что он не зависит от других виджетов на странице или своего родителя.
  • Родитель подписывается на события дочерних виджетов.
  • 2 виджета не общаются друг с другом.
  • Если нужно изменить на основе какого-либо события в другом, то страница становится посредником.
  • Страница прослушивает события из первого виджета и запускает вызовы во второй виджет, заставляя его реагировать наизменение.
  • Данные передаются от виджета 1 к странице, от страницы к виджету 2.
  • Виджеты прослушивают события DOM (такие как щелчок, наведение мыши и т. Д.).Они ловят события, обрабатывают их (извлекают данные, данные массажа и т. Д.) И publish их.

Вы можете использовать для этого пользовательские события jQuery, но для оптимальной производительности используйте этот плагин jQUery, созданный автором Dojo Питером Хиггинсом: pubsub js

5.Другие предложения

  • Используйте инфраструктуру MVC javascript, такую ​​как Backbone.js .
  • Используйте плагины jQuery, но опасайтесь их производительности.jQuery UI, jScrollPane - отличные плагины, которые могут легко создавать панели, которые вы видите на главном трекере

Как видите, это очень широкая тема, и вы можете углубиться в любой изэти разделы.Если у вас есть какие-либо вопросы, дайте мне знать, и я постараюсь их объяснить.

0 голосов
/ 16 июля 2011

Я создаю свои приложения JavaScript, используя шину событий, которая отвечает за логику. Там подключаются бизнес-правила, взаимодействие с сервером, проверка и т. Д. Также визуальные элементы извлекают свои данные через эту шину. Визуальные элементы разрабатываются с использованием MVC независимо друг от друга. Если код становится общим, он получает плагин (я использую jQuery в самой нижней части приложения). Также есть менеджер, который отвечает за поиск и отображение компонентов. Он получает свои команды через шину событий.

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

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