Angularjs的Active Record或Data Mapper模式?

时间:2013-07-02 21:48:43

标签: angularjs angularjs-resource

我对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方法是什么?

1 个答案:

答案 0 :(得分:3)

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
    }
  }
]);