【问题标题】:Is it good to store UI state directly within data model?直接在数据模型中存储 UI 状态好吗?
【发布时间】:2014-02-06 22:21:09
【问题描述】:

这是一个通用架构问题。所以想想 MVC 模型,其中包含数据的模型与某些 UI 字段相关联,因此它们会同时更新。

现在我需要存储一些与该 UI 字段相关联的 UI 状态,例如一个指示该字段是否处于编辑模式的标志。并且 UI 会根据这个编辑标志进行更新,比如当编辑标志为 true 时会显示一些编辑控件。

所以我最好重用数据模型并将状态与其他后端相关数据一起存储(我当然不会将此标志发送回后端,因为后端与 UI 状态无关),或者创建一个新容器来跟踪 UI 状态?

【问题讨论】:

  • 您是否将服务器端称为后端。我将持久存储视为后端,将服务器端编程(例如 java 中的 jsp/servlets 等)视为前端。
  • @pawindergupta 是的,在这种情况下,我将持久存储层称为后端,它处理获取/更新数据库。

标签: angularjs user-interface model-view-controller state


【解决方案1】:

在 ui 表单 /model 变脏后(用户首先开始与表单的第一次交互),您会将模型(自然是 ui)的状态存储在一个对象中,我们称之为“包”。 当用户修改值时,您会不断更新包。在用户尝试离开表单(关闭窗口、在浏览器中来回切换等)之前,您可以将此包保存到 cookie(如果它很小)或发布到您的服务器并将其保存为 json 对象包含 4 个字段的表,例如 id、jsondata、modelUiIdentifier、userIdentifier。稍后加载该页面时,您可以获取此数据(如果该模型/ui 和用户存在该数据)并水合您的模型对象(这将自动更新您的 ui)。

如果您使用 angularjs,只需通过复制相关 ui 部分的 $scope 对象的数据($scope 对象中的非“函数”值并如上所述发送到服务器)来遍历相关 ui 部分的 $scope 对象

【讨论】:

  • 感谢您的建议,这些建议很好。但是他们并没有真正回答我的问题,我问我是否要存储 UI 状态,是否值得在包含数据的 UI 模型中添加 UI 状态标志(例如 editing = true),或者更好将 UI 状态分离到另一个对象中?
  • 你可以这样做。所以,他们会在同一个地方。您可以附加一个像我的 model.editingstate={} 这样的对象,并使用不会污染模型的编辑数据填充它。
  • 如果我想保存 ui 状态,我会单独保存并将状态数据与模型对象 b4 合并显示给用户。我不想让我的模型有这样的额外字段。我希望这会有所帮助
  • 您如何看待拥有一个完全独立的容器来存储状态? IE。根本不碰模型?
  • 这很好,它变成了像对象实例化一样——你不需要将值硬编码到对象中,而是用相关数据实例化它们。以类似的方式,您正在使用相关数据(保存的 ui 状态)为您的模型补充水分。解耦得越多越好,你就不用担心状态会互相绊倒,并且会保持理智。
【解决方案2】:

状态就是数据,数据就是状态。考虑到这一点,如果您需要存储一些与 UI 字段关联的 UI 状态,请使用工厂创建对象。改变那个对象,你就改变了 UI 状态。此外,工厂可以通过简单的注入在您的项目中重复使用,管理不同状态的状态,并且易于测试。

更新:

服务管理数据/状态的简单演示http://plnkr.co/edit/PdDmUz?p=preview

.html

<h3>Controller 1</h3>
  Check me, to check both: 
  <input type="checkbox" ng-model="selected.data" />
  <pre>selected.data: {{selected.data}}</pre>


<h3>Controller 2</h3>
  <div ng-controller="MainCtrl2">
  Or, check me: 
  <input type="checkbox" ng-model="selected2.data" />
  <pre>selected2.data: {{selected2.data}}</pre>

.js

app.controller('MainCtrl', function($scope,uiFieldState) {
    $scope.selected = uiFieldState.uiObject;
})

app.controller('MainCtrl2', function($scope,uiFieldState) {
    $scope.selected2 = uiFieldState.uiObject;
})

app.factory('uiFieldState', function () {
    return {uiObject: {data: null} };
});

【讨论】:

  • 在我看来,我将“数据”称为存储在数据库中的实际数据(如用户名),将其绑定到 UI 的目的是通过 UI 显示并可能更新它。但是,状态是一种纯粹的视觉状态(例如,如果字段处于焦点状态或处于编辑模式),我认为不值得进入包含后端数据的同一模型。那么在您的回答中,您是否建议我将 UI 状态存储在不同的对象中?
  • 用户名“数据”通常用于创建持久授权/权限“状态”服务,任何“编辑模式”功能都将根据用户权限级别“数据”有条件地应用于“状态” '。上面我添加了使用服务对象的 UI 状态示例。这是一个示例应用程序(来自使用 angularJS 的应用程序开发书),其中一个服务使用一个对象来控制诸如“编辑模式”之类的东西github.com/angular-app/angular-app/blob/master/client/src/…
猜你喜欢
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多