帮助学习pivotaltracker的javascript,寻找高级细分

我的javascript技能是相当基本的,我可以使用jquery等。但是当涉及到建立像pivotaltracker这样的网站时,我不知道从哪里开始!

希望有人可以帮助打破他们的javascript架构,并在高层次上解释他们如何设计他们的js frameowork来制作一个像javascript一样的设计gmail(至少我认为是这样)。

像:

  1. 布局明智,是否有一个div容器加载不同的面板?
  2. 它是否保留所有故事的浏览器副本,并使用javascript模板来构建html?
  3. 如何设计各种对象
  4. 我认为这是一个重要的事件,事件是如何联系起来的,这是一个全球性的事件吗?

我觉得有趣的是,页面上有大量的DOM元素,所有的用户故事都组合在一起等,所以他们必须做一些很酷的性能技术,特别是在事件等方面。

我认为你的问题更多的是在javascript中理解MVC( 模型 – 视图 – 控制器 )模式。 我认为您应该更新您的问题以反映这一点。

像’帮助理解javascript中的MVC模式’之类的东西。

如果不提供带有示例的演示用例和详细的代码遍历,很难提炼出javscript中的概念。 我知道这基本上就是你所要求的,但我认为这不属于StackOverflow的职权范围。

例如,MVC模式非常熟悉并广泛用于服务器端框架中。

  • PHP有CodeIgnighter
  • Ruby有Rails
  • Python有Django
  • Java有Spring
  • 每种语言都有很多很多变种。

MVC模式与OOP( 面向对象编程 )的概念紧密相关。 虽然为了遵循MVC模式,语言不是面向对象的基础。 许多MVC框架倾向于按照OOP方法在语言允许的范围内构建。

这是我认为MVC概念在前端开发中不那么普遍的原因之一。 很长一段时间,Javascript一直被误解为一种语言。 因此,最近才有人将OOP的原则应用到javscript中。

浏览器一致性和像JQuery这样的库的改进与此有很大关系。 能够更少关注DOM中不一致的挫折,使人们能够意识到语言本身的核心方面。

(许多人相信并且仍然这样做,浏览器的不一致是JavaScript语言的错误,而不是浏览器厂商对DOM的实现。这是误解Javascript背后的根本原因。)

随着这个小小的咆哮,我将有一个裂缝,给你一个非常高水平的MVC解释。

在MVC框架中,预定义了模型,视图,控制器及其交互方式的创建。 他们这样做是为了保持项目清洁并始终遵循相同的结构。 这样做的好处是……

  1. 参与该项目的新开发人员更容易理解正在发生的事情。

  2. 你在框架中工作的时间越多,你对api的熟悉程度就越高。 因此它加快了开发时间。

  3. 通用结构和api使您和其他人更容易维护代码库。

要了解它们如何在javscript中执行此操作,您需要了解构造函数的function,原型和对象是如何工作的。 这些是核心JavaScript语言的一些基础知识, 雄辩的JavaScript是一个很好的入门之地。

首先,我不认为MVC这个术语的顺序是正确的,以帮助可视化内部流程的流程。 无论这是有意还是无意,我不知道,我猜不同的人会以不同的方式看待事物,但在我看来,MVC更容易说出来并且听起来更好。

我更愿意将其视为CVM。

MVC框架的关键点是逻辑分离。

控制器>>控制器,是应用程序的function部分,每个控制器处理用户交互的特定方面。 然后,它根据收到的输入,通过将更改传递给模型和视图来管理如何处理交互。

MODEL >>模型是关于数据的。 它只有一个工作,为数据建模。 因此,模型通常会获取数据并validation或更改其表示。 该模型还负责CRUD操作(创建,读取,更新,删除)。 对于通过应用程序运行的不同类型的数据,您通常有一个单独的模型。 例如用户,评论,post。

视图>>视图是操作的直观表示。 它从模型中获取数据并生成视觉输出。 虽然视图生成可视输出,但视图本身通常不会执行渲染它的工作。 它只是将可视化表示返回给控制器进行渲染。 视图与整个页面无关,每个视图代表应用程序的不同视觉方面,例如登录对话框,新评论等。

通过分离出这样的应用程序的不同部分。 许多部件可以通过不同的控制器进行互换和重复使用。

在后端MVC框架中,它们响应的用户交互通常是页面请求。 因此,控制器监听来自客户端的请求。 他们使用url和查询参数来确定哪个控制器负责处理该请求。

eg http://myapp.com/users/ >> user Controller 

然后,控制器可以使用URL的任何后续部分来定义它应该用于响应的模型和视图。

 eg 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密集型应用程序(也称为单页面Web应用程序)中是一种低效的方法。 您最终会得到意大利面条代码和function重复。 由于这种方法倾向于导致某人将所有function封装到处理交互的函数中。

例如

 $('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('
  • '+data[key]+'
  • ') }; } }); });

    因此JavaScripts直接处理交互的能力,实际上变得不利。 拥有一个全局对象(如URL)来响应,使得应用程序的部分建模和分离更容易处理和概念化。

    理论上,您可以创建自己的全局对象来存储应用程序状态并监视控制器中的更改。 然而,对于大多数应用程序来说,这是一种不必要的追求,事实certificate,URL对象对于此操作来说既简单又高效。 由于URL在其片段中包含一种状态forms,因此人们可以直接跳转到应用程序的特定部分。 如果您实现自己的对象来完成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对象以指向链接href属性中包含的URL。 但是,只更改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 // Sign up 

    一个单独的函数将监视散列片段的变化。 这可能是location.hash上的setInterval()forms,它将前一个片段与当前片段进行比较,或者由上述函数触发的自定义事件。

    为了允许控制器响应正确的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确实能够直接响应用户交互,所以不应该完全忽略该function。 因此,在一些JavaScript MVC框架中,它们略微污染了纯MVC概念,以允许更深入的交互控制。

    我看到了Ben Nadel在单页网页应用中探索MVC概念的video教程。 它非常详细地介绍了如何构建应用程序。 并且还提供了一些很棒的JavaScript创作技巧。

    一些Javascript MVC框架

    概述了上面提到的一些框架。

    如果你还没有,请不要忘记阅读雄辩的JavaScript

    我希望这是足够的信息让你开始。

    Pivotal Tracker UI(和js)非常类似于Google Wave(Wave in the Box) Wave协议规范所以我认为它具有以下架构。

    主页由html和js loader组成。 Html很简单 – 只是一个没有内容的div。 Loader在页面加载时运行,就像那样

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

    此function运行2个任务:

    • 加载数据(通过AJAX例如)
    • 使用加载的数据构建UI

    加载数据是明确的操作。 构建UI更复杂。 用简单的控件构建UI – 小部件(或某种小部件)。 每个小部件都有一个代码来构建自己,并初始化事件处理程序。 每个加载的窗口小部件都在加载器(或介体)中注册,因此它可以通过加载器访问其他窗口小部件数据。

    为每个小部件构建html使用模板(某种JSP模板)。 模板示例

      
  • <% if (!readOnly) { %> />
    <% } else { %>
    <%= position %>.
    <% } %> <% if (!readOnly) { %>
    <% } %>
  • 模板由模板引擎编译并成为纯HTML代码。

    事件处理程序不是全局的。 每个小部件都自己创建事件处理程序。 如果它是一个需要在每个小部件上触发的全局事件,那么loader(mediator)通过在其列表中注册的每个小部件上调用trigger方法(对于jquery)来触发它。

    设计为关联数组的各种对象。 喜欢

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

    因此,您可以保留任何数量的字段数。

    希望能帮助到你。

    问候,谢尔盖

    嗯,它肯定是一个很好的应用程序,最初看起来令人生畏。 但是,如果将其分解为组件(例如标题,正文,页脚,子窗口小部件),则逐个处理它们变得很容易。

    从我看来,它是用各种“小部件”构建的。 总之,让我选择仪表板页面并向您展示如何设计它。

    1.布局

    从它看起来,它们有3列布局。 您可以根据需要选择固定布局或流畅布局 。

    如果您看一下关键,当调整浏览器大小时面板resize时,它们会为仪表板提供流畅的布局。

    在初始页面加载时,我会渲染三个带有加载符号的空面板。 然后通过带数据的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插件。 最重要的是,如果您将inheritance模型添加到这些插件,您可以拥有可扩展的插件。 这是一个很好的方法,对我来说非常好: 将类附加到jQuery对象

    3.对象设计

    简短回答 – 基于您的视图模型。 您发送给客户端的JSON对象应该是视图模型的子集,其中包含绘制窗口小部件并通过事件启用交互(键,ID等)所需的相关数据。

    4.活动管理

    对于事件管理,我的方式是:

    • 每个小部件都是自包含的。 从某种意义上说,它与页面上的其他小部件或其父级无关。
    • 父级订阅子小部件上的事件。
    • 2个小部件不互相通话。
    • 如果需要根据另一个事件中的某个事件进行更改,则该页面将成为代理。
    • 页面侦听来自第一个窗口小部件的事件,并将调用触发到第二个窗口小部件,使其对更改做出反应。
    • 数据从小部件1冒泡到页面,页面到小部件2。
    • 窗口小部件侦听DOM事件(例如单击,鼠标hover等)。 他们捕捉事件,处理它们(提取数据,按摩数据等)并publish它们。

    您可以为此使用jQuery自定义事件,但为了获得最佳性能 ,请使用由Dojo的作者Peter Higgins创建的这个jQUery插件: pubsub js

    5.其他建议

    • 使用javascript MVC框架,如Backbone.js 。
    • 使用jQuery插件但要警惕它们的性能。 jQuery UI,jScrollPane是一款出色的插件,可以轻松构建您在关键跟踪器上看到的面板

    正如您所看到的,这是一个非常广泛的主题,您可以在每个部分中尽可能深入。 如果您有任何疑问,请告诉我,我会尽力解释。

    我使用负责逻辑的事件总线创建我的javascript应用程序。 在那里插入业务规则,服务器交互,validation等。可视元素也通过该总线检索它们的数据。 使用独立于MVC的MVC设计可视元素。 如果代码被共享,它会获得一个插件(我在应用程序的botom上使用jQuery)。 还有一位负责查找和显示组件的经理。 它通过事件总线获取命令。

    我喜欢这个设计,因为它非常灵活,非常适合用于事件处理的语言javascript。