【问题标题】:Active Record or Data Mapper pattern for Angularjs?Angularjs 的活动记录或数据映射器模式?
【发布时间】:2023-04-08 09:39:01
【问题描述】:

我对 Angular 很陌生,所以希望我知道的足够多,可以提出一个看似合理的设计问题。

我正在通过 Angular 绘制一些数据,并且正在使用 $resource。在将 Angular 引入项目之前,我创建了一个图表工厂函数,用于从我刚刚粘贴到视图中的示例 json 数据创建图表对象。

现在我在使用 Angular,很想将图表功能放入 Active Record 样式的“图表”资源中,这样我就有了一个可以绘制、保存、更新等的东西。

虽然该模式的优点是简单,但缺点是将持久性与行为相结合。例如,如果我想将图表设置保存到本地存储,那就很尴尬了。

在我的职业生涯中已经被 AR 咬了足够多的时间,我想与 DM 保持一致,让我的图表对象保持原样,让控制器将数据从资源传递到我的图表。

但是!我对 angularjs 依赖注入的模糊理解表明我可能能够创建一个资源或一些可以接受通用持久性接口的资源 - 正确的词是“范围”吗?

AR 策略示例:

App.factory('Chart', [
  '$resource', function($resource) {
    var chart = $resource('/api/charts/:id', {
      id: '@id'
    });

    chart.draw = function() { ... }

    return chart
  }
]);

App.controller('ChartsCtrl', [
  '$scope', 'Chart', function($scope, Chart) {
    $scope.charts = Chart.query(function() {
      $.each($scope.charts, function(i, c) { c.draw() })
    })
  }
])

DM 策略示例:

App.chart = function(resource) {
  return { draw: function() { ... } }
}

App.factory('ChartResource', [
  '$resource', function($resource) {
    return $resource('/api/charts/:id', {
      id: '@id'
    })
  }
])

App.controller('ChartsCtrl', [
  '$scope', 'ChartResource', function($scope, ChartResource) {
    $scope.charts = $.map(ChartResource.query(), function(i, resource) {
      chart = App.chart(resource)
      chart.draw()
      return chart
    }
  }
])

我认为还有第三种方法,但我没有看到,因为我不太了解如何利用 DI。

换句话说,AngularJS 用什么方法来创建具有可交换持久性策略的对象?

【问题讨论】:

  • 这应该更明显,因为这是设计严肃的 AngularJS 应用程序时的常见问题。
  • 我在考虑 ChartResource 将依赖于 Chart,并在调用中添加一个回调,它将接收到的数据并从中创建一个新的 Chart 实例。这样,控制器可以调用 ChartResource 或 LocalStorageChart(或调用 LocalStorageChart 并使用 ChartResource 作为后备的服务\当时间到期失效时)。你怎么看?

标签: angularjs angularjs-resource


【解决方案1】:

DataMapper 策略实际上已经是依赖注入的一种形式。您正在将所需的持久性实现传递给 Chart 构造函数,并且您可以在每个new 的基础上传递一个不同的实现。非 DI 方法是对持久性实现进行硬编码,就像在 ActiveRecord 样式的示例中一样。

DataMapper 不是 Angular.JS 特定意义上的 DI。 Angular 的 DI 并没有真正让你在运行时交换实现。但是,您可以使用官方的ngMock 模块来实现这一点。 ngMock 应该用于测试,因此在该场景之外这可能不是一个好主意。

对于这类事情,似乎没有特定于 Angular.JS 的约定。事实上,Angular.JS 并没有太多的约定。

您可以选择提供一个单独的方法来随时更改持久性机制,而不是在构造函数中传递实现。例如,使用ChartResource 进行基于网络的初始检索,然后切换到IndexedDB 以将它们存储在本地:

// ChartResourceIndexedDB: same API as $resource but uses local IndexedDB
app.factory('ChartResourceIndexedDB', /* .. */);

app.controller('ChartsCtrl', [
  '$scope', 'ChartResource', 'ChartResourceIndexedDB',
  function($scope, ChartResource, ChartResourceIndexedDB) {
    $scope.charts = $.map(ChartResource.query(), function(i, resource) {
      chart = App.chart(resource)
      chart.draw();
      chart.setPersistence(ChartResourceIndexedDB);
      chart.save();
      return chart
    }
  }
]);

【讨论】:

    猜你喜欢
    • 2017-07-15
    • 2023-01-27
    • 2014-08-03
    • 2010-09-17
    • 1970-01-01
    • 2010-10-05
    • 2013-11-07
    • 1970-01-01
    • 2010-09-10
    相关资源
    最近更新 更多