Object oriented approach with AngularJS
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.
vonwolf
Updated on June 28, 2022Comments
-
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.
Thanks for your insights
-
vonwolf almost 10 yearsThis 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 almost 10 yearsI 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 almost 10 years@domokun how does the
new myFactory()
work in your case? The factory returns an object, so you can't normally callnew ...()
on that. Are you doing some additional trickery? I getobject is not a function
running that. -
ashok_khuman over 8 yearsBut we shouldn't create Service inside a controller