【问题标题】:How to build big applications如何构建大型应用程序
【发布时间】:2014-06-10 20:26:07
【问题描述】:

我想知道如何构建我的应用程序。我应该使用自定义视图和一个控制它们的主视图吗?还是将我的观点保存在灯箱中更好。我发现的所有示例都在某种程度上限制了功能,并且只显示了一个或几个屏幕。组织更大的应用程序的正确方法是什么?

【问题讨论】:

  • 问题必须更具体。此类问题应在相关论坛上讨论。
  • 我想不出比这更具体的问题了。您可以贡献个人实践、示例、链接等。
  • 您是否要求我们为您发送我们的大项目?
  • 不,我想解释一下你是如何构建它的
  • 没有正确答案,有很多方法可以解决,取决于您使用的其他技术。

标签: famo.us


【解决方案1】:

我也想知道。

起点:

  • Famo.us 应用采用分层渲染树结构。
  • Famo.us 使用 RequireJS 模块。
  • Famo.us 鼓励使用视图
    • 视图是可重用的组件。
    • 视图封装了功能(以及渲染树的一部分)。
    • 视图使用事件进行通信。
    • 视图由 options 对象初始化。

我们需要添加结构来管理:

  • 业务逻辑
  • REST api 调用、音频、本地存储等非 UI 功能。
  • 数据流:
    • 更新用户输入数据
    • 更新数据更改视图

模块、事件和松散耦合

目标:

  • 可扩展的应用程序结构。
  • 小型、独立、可测试的模块。
  • 促进代码的重用。
  • 轻松共享模块(只需将文件拖放到您的项目中)
  • 不依赖其他 Javascript 框架。

通常,模块之间存在紧密耦合:

  • 模块实例化并保持对另一个模块的引用
  • 模块跨越了它们的语义边界
    • 了解特定 REST api 的视图
    • 使用特定模型代码的视图,例如 Backbone(参见 Taasky 示例)

以下是如何避免这种情况:

  1. 当发生有趣的事情(用户输入、数据更改等)时,模块会发出事件
  2. Mediator 监听事件
  3. Mediator 调用另一个模块的公共 API。

因此,它不会让 View-module 知道 Backbone 模型的内容,而是发出这样的用户输入事件:

  1. Todo-Edit-View 发出“用户输入”事件:"todo-update",{id:1,title:'Code'}
  2. Todo-Mediator 监听事件。
  3. Todo-Mediator 调用 Todo 模块的 tasks.find({id:1}).update({title:'Code'})(例如使用 Backbone)

规则

  • 有模块和中介
  • 模块具有公共 API 并发出事件
  • API 和事件保持在其语义边界内;即“updateTitle()”而不是“onBackboneModelChange()”
  • Mediator 将应用程序耦合起来,即骨干模型更改与待办事项标题更新。
  • 中介是单身人士
  • 一个应用程序可以有多个中介。

例如,像 GMail 这样的电子邮件应用程序可以有中介用于

  • 聊天功能
  • 待办事项列表功能
  • 阅读电子邮件
  • 撰写和发送电子邮件

文件结构:

/src
   /lib
   /services
   /mediators
   /layout
   /content
   /config
   /main.js

模块类型:

  • Service:独立模块,封装非UI功能如:LocalStorage、Ajax、Web Audio等。
  • 布局:内容的布局、动画和定位,例如:ScrollView、HeaderFooterView等
  • 内容:应用的实际内容:渲染树的叶节点(表面)。

注意布局内容之间的区别。通过将 UI 组件和布局与实际内容分离,可以轻松重用 UI 模式,例如侧面板、弹出窗口、导航栏、粘性标题、滚动视图等。

另外,我建议为每个仅包含 结构 和最少主题的 Layout 创建一个 *.css。所有主题都可以在config/theme.css 中覆盖/扩展,因此很容易重新设计应用程序。

其他代码:

  • Mediator:使用事件和公共 API 耦合模块。
  • 配置:包含整个应用程序在初始化时使用的所有选项。
  • ma​​in.js:引导应用程序。

Main.js 中的引导应用程序

  1. 创建中介
  2. 创建服务
  3. 构造渲染树

模块生命周期

  • 模块必须包含在单个文件中,即不要依赖外部库!

当一个模块被创建时,它会向所有中介宣布它的存在。我们使用 Famo.us Engine 来发出一个全局事件。这将是唯一必需的依赖项!

 Engine.trigger('created',this)

当一个模块被销毁时,它会向所有中介宣布它的销毁。

 Engine.trigger('destroyed',this)

中介器监听createddestroyed 事件并将模块粘合在一起:

 var someDataModule; // Backbone or whatever
 Engine.on('create',function(module){
    if(module instance of SomeDataModule) {
        var someDataModule = module;
    }
    if(module instanceof TodoView) {
      module.on('change-title',function({id:id,title:title}){
          someDataModule.find({id:id}).set('title',title);
      })
    }
 }) 

在简单的中介中,您可以按顺序初始化模块(即SomeDataModuleTodoView 之前)。但是,在更复杂的场景中,您可能需要使用 Promise 来耦合所有内容。

依赖关系说明

“自包含”模块有三个例外:

  1. LayoutContent 模块允许具有分层依赖关系。父母可以初始化孩子,并期待这些孩子的某些事件。 ListView 可能会初始化 ItemView 并处理 ItemRemoved 事件。

  2. Services 可以是另一个服务的 Facade/Adapter。例如,DataService 可能为RestApiService 提供简化、抽象和安全层。

  3. 当然,中介具有硬连接的依赖关系,因为它们耦合了应用程序!

【讨论】:

    【解决方案2】:

    Famo.us 专注于 UI,因此您最好寻找一种 MVC 模式以具有更好的结构,特别是在大型项目中,实际上由于 Famo.us 非常年轻,它只与 Angular 集成:

    http://famo.us/integrations/angular/

    但众所周知,他们将在不久的将来添加其他 MVC 集成

    试试 Angular,看看它是否是你需要的,它是一个非常好的 MVC 框架,我的建议是首先学习 Angular 至少基础知识 (http://angularjs.org/,然后在 Famo.us 大学学习 (http://famo.us/university) 你可以了解这种整合

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2017-02-22
    • 2016-01-03
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多