javascript - AngularJS 的单对象模型

标签 javascript angularjs model-view-controller model angularjs-scope

我正在 AngularJS 中试验一些最佳实践,特别是在设计模型方面。在我看来 AngularJS 的一个真正的力量是

'When model changes view gets updated & vice versa'

.这导致了显而易见的事实

'At any given time the model is the single source of truth for application state'

现在,在阅读了有关设计正确模型结构的各种博客文章后,我决定使用类似“单一对象”的方法。这意味着整个应用程序状态都在单个 JavaScript 对象中维护。

待办事项应用示例

$scope.appState = {
name: "toDoApp",
auth: {
    userName: "John Doe",
    email: "john@doe.com",
    token: "DFRED%$%ErDEFedfereRWE2324deE$%^$%#423",
},

toDoLists: [        
  { name: "Personal List", 
    items: [
      { id: 1, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 0},
      { id: 2, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 1},
      { id: 3, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 0}]
  }, 
  { name: "Work List", 
    items: [
      { id: 1, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : -1},
      { id: 2, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 0},
      { id: 3, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 0}]
  }, 
  { name: "Family List", 
    items: [
      { id: 1, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 2},
      { id: 2, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 0},
      { id: 3, task: "Do something ", dueDate: "2013-01-10 11:56:05", status:"Open", priority : 5}]
  }
]        

};

根据应用程序的复杂性,这个对象会变得很大。关于这一点,我有以下担忧并将其标记为问题。

  • Is such approach advisable? What are the downsides and pitfalls I will face when application starts to scale?

  • When small portion of object is updated say priority is increased will angular smartly re-render the delta alone or will it consider the object got changed and re-render whole screen? (This will lead to poor performance), If so what are the works around?

  • Now since the whole DOM got smoothly translated into one JavaScript object the application has to keep manipulating this object. Do we have right tools for complex JavaScript object manipulation like jQuery was king of DOM manipulator?

带着以上疑惑,我强烈地发现了以下优点。

  • 数据已被整齐地抽象和组织得井井有条,以便随时 可以序列化到服务器、firebase 或本地导出到用户。

  • 实现崩溃恢复将很容易,将此功能视为桌面中的“休眠”选项。

  • 模型和 View 完全分离。例如,公司 A 可以编写 Model 来维护状态,并编写几个明显的 Controller 来更改 模型和一些与用户交互的基本 View 。现在这家公司A 可以邀请其他开发者公开写下自己的看法, 向公司 A 请求更多的 Controller 和 REST 方法。这个 将赋能精益开发。

  • 如果我开始将此对象版本控制到服务器,我可以以用户查看网站的相同方式向用户播放,并且可以继续轻松工作,会怎样?这将作为单页应用程序的真正后退按钮。

最佳答案

在我的日常工作中,我们在大型企业 AngularJS 应用程序中使用“单个对象中的状态”模式。到目前为止,我只能看到好处。让我回答您的问题:

Is such approach advisable? What are the downsides and pitfalls I will face when application starts to scale?

我看到两个主要好处:

1) 调试。当应用程序扩展时,最难回答的问题是我的应用程序现在发生了什么?当我将所有应用程序状态集中在一个时对象,我可以随时在应用程序运行时将它打印在控制台上。

这意味着当发生错误时更容易理解发生了什么,您甚至可以在生产应用程序中执行此操作,而无需使用调试工具。

主要使用处理状态对象(或其部分)的纯函数编写代码,将这些函数和状态注入(inject)控制台,您将拥有最好的调试工具。 :)

2) 简单性。当您使用单个对象时,您会非常清楚地知道您的应用程序中哪些更改 状态以及哪些读取 状态。它们是完全独立的代码片段。让我用一个例子来说明:

假设您有一个“结帐”屏幕,其中包含结帐摘要、运费选项和付款选项。如果我们使用单独的内部状态实现SummaryFreightPaymentOptions,这意味着每次用户更改其中一个组件,您必须显式更改其他内容

因此,如果用户更改了Freight 选项,您必须以某种方式调用Summary,以告诉它更新其值。如果用户选择带有折扣的 PaymentOption,也会发生同样的情况。你能看到意大利面条代码构建吗?

当您使用集中状态对象时,事情会变得更容易,因为每个组件只与状态对象交互Summary 只是状态的一个纯函数。当用户选择新的运费或付款选项时,状态会更新。然后,Summary 自动更新,因为状态刚刚改变。

When small portion of object is updated say priority is increased will angular smartly re-render the delta alone or will it consider the object got changed and re-render whole screen? (This will lead to poor performance), If so what are the works around?

我们在将此架构与 Angular 一起使用时遇到了一些性能问题。当你在对象上使用观察者时,Angular 脏检查工作得很好,但当你使用昂贵的函数时效果不佳。因此,我们在发现性能瓶颈时通常做的是将函数结果保存在 $scope 上设置的“缓存”对象中。每次状态改变时,我们都会重新计算函数并将其保存到缓存中。然后在 View 上引用此缓存。

Now since the whole DOM got smoothly translated into one JavaScript object the application has to keep manipulating this object. Do we have right tools for complex JavaScript object manipulation like jQuery was king of DOM manipulator?

是的! :) 由于我们有一个大对象作为我们的状态,因此可以在此处使用为操作对象而编写的每个库。

您提到的所有好处都是真实的:它可以更轻松地拍摄应用程序的快照、序列化它、实现撤消...

我又写了一些implementation details of the centralized state architecture in my blog .

同时查找有关基于集中状态思想的框架的信息,例如 Om , MercuryMorearty .

关于javascript - AngularJS 的单对象模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24054950/

相关文章:

javascript - 在数字字段中放置逗号

javascript - 如何找到嵌套在 JSON 中的列的最大值?

mysql - 在 AngularJS 和数据库之间保持唯一标识符同步的最佳方法是什么?

javascript - jstree不添加新节点

javascript - 使用 angularjs 更新值的问题

mysql - Rails 如何修复表以获取任何 url

python - 在 Django 中,放置 HTML 格式数据的简短片段的最佳位置在哪里?

java - 如何在两个Spring Controller 内传递参数

javascript - 比较两个对象数组并合并缺失的对象

angularjs - session 超时 - Spring boot + Angular 应用程序中的 HTTP 状态代码 -1