Object oriented approach with AngularJS

15,121

Solution 1

I think that the closest structure to an Object it's probably a factory, for several reasons:

Basic Syntax:

.factory('myFactory', function (anInjectable) {

  // This can be seen as a private function, since cannot
  // be accessed from outside of the factory 
  var privateFunction = function (data) {
    // do something 
    return data
  }

  // Here you can have some logic that will be run when 
  // you instantiate the factory
  var somethingUseful = anInjectable.get()
  var newThing = privateFunction(somethingUseful)

  // Here starts your public APIs (public methods)
  return {
    iAmTrue: function () {
      return true
    },

    iAmFalse: function () {
      return false
    },

    iAmConfused: function () {
      return null
    }
  }
})

And then you can use it like a standard Object:

var obj = new myFactory()

// This will of course print 'true'
console.log( obj.iAmTrue() )

Hope this helps, I perfectly know that the first impact with angular modules can be pretty intense...

Solution 2

You would use an angular service.

All angular services are singletons and can be injected into any controller.

Ideally you would keep only binding/actions on html in your controller and the rest of the logic would be in your service.

Hope this helps.

Solution 3

I got idea by evaluating this library : https://github.com/FacultyCreative/ngActiveResource

However this library assumes strict rest so I it wasn't work for me. What did work for is this:

I created base Model

var app = angular.module('app', []);

    app .factory('Model', function(){
        var _cache = {};  // holding existing instances 
        function Model() {
           var _primaryKey = 'ID',
               _this = this;

              _this.new = function(data) {
                 // Here is factory for creating instances or 
                 // extending existing ones with data provided
               }  

       }

       return Model;
}); 

Than I took simple function extensions "inherits"

Function.prototype.inherits = function (base) {
        var _constructor;
        _constructor = this;
        return _constructor = base.apply(_constructor);
    };

and now I cam creating my models like this

app.factory('Blog', [
   'Model',
   '$http',
   function(Model, $http) {
     function Blog() {
      // my custom properties and computations goes here
      Object.defineProperty(this, 'MyComputed' , {
        get: function() { return this.Prop1 + this.Prop2  }
      });
     }

     // Set blog to inherits model
     Blog.inherits(Model);

    // My crud operations 

    Blog.get = function(id) {
     return $http.get('/some/url', {params: {id:id}}).then(function(response) {
       return Blog.new(response.data);
     });
    }

    return Blog;

   }
]);

Finally, using it in controller

app.controller('MyCtrl', [
   '$scope', 'Blog',
    function($scope, Blog) {
      Blog.get(...).then(function(blog) {
        $scope.blog = blog;
      });
    }
])

Now, there is much more in our Model and extensions but this would be a main principle. I am not claiming this is best approach but I am working pretty big app and it really works great for me.

NOTE: Please note that I typed this code here and could be some errors but main principle is here.

Share:
15,121
vonwolf
Author by

vonwolf

Updated on June 28, 2022

Comments

  • vonwolf
    vonwolf almost 2 years

    It seems that Angular does not provide a built-in solution to define class instances with properties and methods and that it's up the developer to build this.

    What is the best practice to do this in your opinion? How to you link this with the backend?

    Some of the tips I have gathered use factory services and named functions.

    Sources : Tuto 1 Tuto 2

    Thanks for your insights

  • vonwolf
    vonwolf almost 10 years
    This seems easy to implement; what would be perfect would be to link this somehow to the schema I have defined on node side with mongoose so that I get the properties from where they are defined instead of rewriting them and combine them with methods from the angular service. I was thinking about ngResource but haven't been successful building the working case. Would that make sense?
  • domokun
    domokun almost 10 years
    I am not sure about that. It seems to me that by doing this (and I don't know if it's feasible or not) you're trying to couple Frontend and Backend. As a rule of thumb, the more decoupled, the better. Anyway, ngResource is just a wrapper for the $http resource, which I personally don't like.
  • Lycha
    Lycha almost 10 years
    @domokun how does the new myFactory() work in your case? The factory returns an object, so you can't normally call new ...() on that. Are you doing some additional trickery? I get object is not a function running that.
  • ashok_khuman
    ashok_khuman over 8 years
    But we shouldn't create Service inside a controller