symfony - 使用 YUI3 (Y.App) 和 Symfony2 进行渐进式增强

标签 symfony yui3 progressive-enhancement

我们实际上使用 Symfony 2 PHP 框架和 Twig 作为模板引擎。
我们认为我们可以避免 View 层的代码重复并从渐进增强 (p-jax) 中受益。

当前状态:

PJAX 不处理基于路由的页面布局的部分更新。
我们的目标是实现一个系统,当导航由 Y.App(路由)处理时,只会更新一些页面“片段”(HTML 节点)。

在这方面,我们开始在以下位置实现 POC:https://github.com/benjamindulau/PocSfYui/
Javascript 可以在这里找到:https://github.com/benjamindulau/PocSfYui/tree/master/src/Acme/PocBundle/Resources/public/js
还有Y.App初始配置:https://github.com/benjamindulau/PocSfYui/blob/master/src/Acme/PocBundle/Resources/views/layout.html.twig#L66

这个想法是,当我们第一次加载页面时,一切都在服务器端处理(渐进增强),这意味着整个页面和页面片段都由服务器呈现。
对于应由 Y.App 执行的下一个请求,我们定义了如下 JSON 格式(/photos 路径响应):

{
    "title": "MyAwesomeWebsite - Photos", // page <title>,
    "fragments": {
        "sidebar": "<h2>Sidebar Menu<\/h2><!-- etc.... -->", // ..... maybe an updated menu for active page
        "main": "<h2>Photos<\/h2><div id=\"photo-list-container\"><ul id=\"photo-list\"><!-- photo items.... --></ul></div>", // Pre-rendered photo list
    },
    "templates": {
        "photo_item_tpl": "<li data-id=\"{{index}}\"><img src=\"{{url}}\" alt=\"{{title}}\" \/><\/li>" // template used later by Y.App for adding new photos
    }
}

这基本上是当前 View 内容(路由)的“JSON 化”版本。

在服务器端,我们检测到请求来自 Y.App,我们没有渲染我们的 Twig 模板,而是从中提取“ block ”并构造这个 JSON 响应,其中包含需要更新的页面片段 + 客户端需要的 Handlebars 模板这个特定的页面。

在客户端(Y.App):
  • 我们定义了一个代表整个页面布局的基本 PageCompositeView,然后定义了一个 Page2colLeftView,它继承自它并实例化了自己的 subview :SidebarView、MainView、HeaderView、...。
  • 我们编写了一个 IO 模块来伪造我们的 PJAX-Like 请求。我们使用它来代替“loadContent”(参见:https://github.com/benjamindulau/PocSfYui/blob/master/src/Acme/PocBundle/Resources/views/layout.html.twig#L93)
  • 在第一次加载时,我们调用 showView 并尝试将我们的页面 subview “重新连接”到它们各自的容器(参见:https://github.com/benjamindulau/PocSfYui/blob/master/src/Acme/PocBundle/Resources/public/js/views/page.js#L27)
  • 在页面中导航时,Y.App 了解页面结构。

  • 假设我们在浏览器中直接加载“/photos”路径:
    1.服务器渲染包含照片列表的整个页面
    2. YUI App 创建它的 PageCompositeView 并将每个 subview 重新连接到它的容器
    3. YUI App 知道“MainView” View (对应于主要内容)应该包含绑定(bind)到“PhotoModelList”模型列表的“PhotoListView” subview 。因此,“/photos”路径上的回调会创建“PhotoView”实例并将其重新连接到其容器(由服务器渲染)。

    2和3(尤其是3)是手动完成的。

    POC 确实有效。

    但在更进一步之前,我们很乐意听取您的建议。

    首先,您如何看待这个 POC?

    我们实际上看到了这种方法的利弊。

    我们主要关心的是我们如何调整 Y.App 来实现我们想要的:
    - 单个复合 View
    - 在第一次加载时,模型通过读取现有的 DOM 重新水化(即:当照片列表由服务器呈现时)
    - 我们越往前走,就越觉得我们遗漏了 Y.App 的一些东西,并且我们采取了错误的方式 ;-)

    但所有这一切的积极方面是我们可以构建一个完整的异步网站,而无需太多工作。

    我们的主要目标是通过提供“几乎完整”的通用解决方案来保持一切可维护。

    也许从该消息中出现的主要问题是:

    “我们使用 Y.App 的方式是否正确?” ;-)

    所以你怎么看 ?

    谢谢,
    氰酸

    最佳答案

    对于 CMS 管理的 POC,我做了几乎相同的操作,但有 2 个不同:PJAX 响应仍然是一个 HTML 片段,它包含一个带有 JSON 编码数据的脚本标签,因此无需查询 DOM 来重新水化我的模型/模型列表,我们使用其中已有的数据。这允许不依赖任何标记来获得正确的模型,但另一方面,这使得响应的大小有点大(但仍然比整个页面加载轻得多)。

    此外,JSON 编码的数据还可能包含一些设置,例如告诉您的 Y.App 要使用哪个 View 、在哪里可以找到相应的 DOM、模板或其他...

    这在 YUILibrary 论坛上讨论过:http://yuilibrary.com/forum/viewtopic.php?t=11877所以你可以在这里找到其他细节。

    对于“我们是否以正确的方式使用 Y.App ?”问题,我认为没有真正的回应。我的意思是 YUI App 框架是那种让你做任何你想做的事的框架,这只是一个权衡给你的约束的问题。如果您查看几个 YUI App 示例,它们都有非常不同的策略。

    但无论如何,您的解决方案对我来说似乎很好,我很高兴看到仍然有人构建逐步增强的应用程序:-)

    关于symfony - 使用 YUI3 (Y.App) 和 Symfony2 进行渐进式增强,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15504406/

    相关文章:

    php - 如何在 Doctrine2 查询生成器中使用 'interval'

    javascript - 为什么在指定 YUI 模块时需要 YUI.add,如果需要,非 YUI 模块如何工作?

    javascript - 检测对给定 JavaScript 事件的支持?

    symfony - Symfony2 服务的外观模式

    url - 如何在 KnpPaginatorBundle 中使用友好的 URL

    yui - 如何在YUI 3中获取选择框值?

    javascript - YUI3 JavaScript : get CSS for placeholder text

    html - 如何通过渐进增强在CSS中提供多层次支持

    javascript - 禁用 Javascript 时重新加载 ajax 的整页

    php - 学说 : Uknown column type