Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Models and Collections in Angular?

I'm coming from Backbone so perhaps my perspective is prejudiced by that but I'm having trouble seeing the best way to model data in Angular. The 2-way data-bind is pretty awesome but past that when I want to have persistent collection and model classes I'm confused.

I'm using to being able to define a collection, say of users, and then being able to call .fetch() whenever I want to update it with new models. As well I can define custom methods on the collection as well as each model.

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

I've looked at Restangular and ngActiveResource so far and neither one seems to offer the same kind of functionality as I would expect.

Is there something I'm missing or perhaps I'm thinking about this in a non-Angular way?

EDIT: I ended up making my own models/collections very similar to Backbone's if it helps anyone: https://github.com/evanhobbs/angular-models

like image 860
Evan Hobbs Avatar asked Jun 12 '14 15:06

Evan Hobbs


People also ask

What is collections in angular?

angular-collection is a bower component you should be able to install it by running: bower install angular-collection. or if you already have a bower based project you can add angular-collection to your dependency list in bower.json. "dependencies": {

What is meant by model in angular?

The model in an MVC-based application is generally responsible for modeling the data used in the view and handling user interactions such as clicking on buttons, scrolling, or causing other changes in the view. In basic examples, AngularJS uses the $scope object as the model.

What is SelectionModel angular?

SelectionModel is a utility for powering selection of one or more options from a list. This model is used in components such as the selection list, table selections and chip lists.

What is a CollectionViewer?

CollectionViewer. Interface for any component that provides a view of some data collection and wants to provide information regarding the view and any changes made.


2 Answers

This is indeed a very interesting question,and I'd like people to think about solutions. In theory,you could stick with Backbone models.It may have a performance cost but.There is no reason it wouldnt work.

Develop your model layer,without thinking about AngularJS.Then you'd have to extend your models and add a listener in your initialize function that would trigger a $rootScope.$apply whenever the model changes,same for any collection you might use.Something like :

/*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);
    };

}

and the view

<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

Now in my opinion,AngularJS works better with raw js hashes.But If you need to port something to AngularJS from Backbone,it can be a solution if already have a strong model layer.

EDIT:it might work without the expensive $rootScope.$apply,

like image 195
mpm Avatar answered Sep 30 '22 15:09

mpm


js-data-angular might be a solution for your problem. It defines collections, their relations and different storage adapters with their fetching functionality.

like image 27
Raymundus Avatar answered Sep 30 '22 13:09

Raymundus