【问题标题】:Models and Collections in Angular?Angular 中的模型和集合?
【发布时间】:2025-11-30 15:05:02
【问题描述】:

我来自 Backbone,所以也许我的观点对此有偏见,但我无法看到在 Angular 中建模数据的最佳方式。 2-way data-bind 非常棒,但是当我想要拥有持久化集合和模型类时,我感到很困惑。

我习惯于定义一个集合,比如用户,然后在我想用新模型更新它时调用 .fetch() 。我还可以在集合以及每个模型上定义自定义方法。

var users = new UserCollection();
users.fetch();
users.doSomethingCustom()
users.at(0).doSomethingModel();

到目前为止,我已经查看了 Restangular 和 ngActiveResource,但似乎两者都没有提供与我预期相同的功能。

我是否缺少某些东西,或者我正在以非 Angular 的方式考虑这个问题?

编辑:如果对任何人都有帮助,我最终会制作出与 Backbone 非常相似的模型/系列:https://github.com/evanhobbs/angular-models

【问题讨论】:

  • 这是你想要的!
  • 好吧,如果可以的话,我不想重新发明*。建模数据似乎是一个很常见的问题,我很惊讶尚未找到社区解决方案。
  • 我认为您想要的是定义一个包含集合的 Angular 服务。服务可以从数据库加载集合,然后您需要做的就是定义服务的功能。不过我确实喜欢 Restangular,你应该更多地研究它并尝试一下,在我看来,它比 Angular 的 $resource 更适合使用 API。
  • 我现在使用过restangular,虽然它非常适合与其他资源交互,但它并不是真正的数据建模解决方案,除非在相当简单的应用程序中。我最终推出了自己的模型和集合基类。

标签: javascript angularjs backbone.js restangular


【解决方案1】:

这确实是一个非常有趣的问题,我希望人们思考解决方案。 从理论上讲,您可以坚持使用 Backbone 模型。它可能会有性能成本,但没有理由不工作。

开发您的模型层,而不考虑 AngularJS。然后您必须扩展您的模型并在初始化函数中添加一个侦听器,该侦听器将在模型更改时触发 $rootScope.$apply,对于您可能的任何集合都是如此使用。类似的东西:

/*global angular,Backbone*/
angular.module('ng')
    .value('Backbone', Backbone)
    .factory('AngularModel', function(Backbone, $rootScope) {
        return Backbone.Model.extend({
            initialize: function() {
                this.on('all', function() {
                    if (!$rootScope.$$phase) {
                        $rootScope.$apply();
                    }
                });
            }
        });
    })
    .factory('AngularCollection', function(AngularModel, $rootScope) {
        return Backbone.Collection.extend({
            model: AngularModel,
            initialize: function() {
                this.on('all', function() {
                    if (!$rootScope.$$phase) {
                        $rootScope.$apply();
                    }
                });
            }
        });
    });

function Main($scope, AngularCollection) {
    $scope.collection = new AngularCollection([{
        name: "foo"
    }, {
        name: "bar"
    }, {
        name: "baz"
    }]);
    $scope.addModel = function(model) {
        $scope.collection.add(model);
    };

}

还有风景

<body ng-app ng-controller="Main">
    <div ng-repeat="model in collection.models">{{model.get('name')}}</div>
    <form name="model_form" ng-submit="addModel(model)">
        <fieldset>
            <legend>Add model</legend>
            <label for="">Name</label>
            <input type="text" ng-model="model.name" />
            <input type="submit" />
        </fieldset>

    </form>
</body>

Some DEMO HERE

现在,在我看来,AngularJS 与原始 js 哈希一起工作得更好。但是如果你需要从 Backbone 将某些东西移植到 AngularJS,如果已经有一个强大的模型层,它可能是一个解决方案。

编辑:它可能在没有昂贵的 $rootScope.$apply 的情况下工作,

【讨论】:

  • 这是一个非常酷的想法——我们已经有几个应用程序共享一个 Backbone 模型层,因此这意味着更少的重新发明*。如果只有一种方法可以在没有 $rootScope.$apply() 的情况下更好地集成它,而且我们还相当依赖模型事件,如果不通过 model.set() 就不会触发
【解决方案2】:

js-data-angular 可能是您的问题的解决方案。它定义了集合、它们的relations 和具有获取功能的不同存储适配器。

【讨论】: