javascript AngularJS 的面向对象方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24548100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Object oriented approach with AngularJS
提问by vonwolf
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.
Angular 似乎没有提供内置的解决方案来定义具有属性和方法的类实例,而由开发人员来构建它。
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
感谢您的见解
采纳答案by domokun
I think that the closest structure to an Object it's probably a factory
, for several reasons:
我认为最接近 Object 的结构可能是 a factory
,原因如下:
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...
希望这会有所帮助,我完全知道角度模块的第一次影响可能非常强烈......
回答by link
You would use an angular service.
您将使用角度服务。
All angular services are singletons and can be injected into any controller.
所有 Angular 服务都是单例的,可以注入到任何控制器中。
Ideally you would keep only binding/actions on html in your controller and the rest of the logic would be in your service.
理想情况下,您只会在控制器中保留 html 上的绑定/操作,其余逻辑将在您的服务中。
Hope this helps.
希望这可以帮助。
回答by Andrej Kaurin
I got idea by evaluating this library : https://github.com/FacultyCreative/ngActiveResource
我通过评估这个库得到了想法: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.
注意:请注意,我在此处输入了此代码,可能会出现一些错误,但主要原理在这里。
回答by vonwolf
As my question does not really reflect the issue I was facing, I'll just post my approach for the sake of it : As Domokun put it, rule of thumb is to decouple front and back. But as I am only building a prototype and managing both ends, I would like to keep things in only one place and let the rest of the application use the central information as a service.
由于我的问题并没有真正反映我所面临的问题,因此我将发布我的方法:正如 Domokun 所说,经验法则是前后分离。但是由于我只是在构建原型并管理两端,所以我希望只将东西放在一个地方,让应用程序的其余部分使用中央信息作为服务。
What I want to do here is to build a form through ng-repeat containing the model fields and most importantly how to display information in the form (e.g. 'Last name' instead of 'lastname')
我想在这里做的是通过 ng-repeat 构建一个包含模型字段的表单,最重要的是如何在表单中显示信息(例如“姓氏”而不是“姓氏”)
So as I started working around with mongoose models here's what I have managed to do :
因此,当我开始使用猫鼬模型时,我设法做到了:
Firstly, it is possible to pass the mongoose schema of a model from node side to angular side with an app.get request with the following response :
首先,可以使用具有以下响应的 app.get 请求将模型的猫鼬模式从节点侧传递到角侧:
res.send(mongoose.model('resources').schema.paths);
this spitts out an object containing all fields of the 'resources' collection. On top of that I included some additional information in the model like this :
这会吐出一个包含“资源”集合的所有字段的对象。最重要的是,我在模型中包含了一些附加信息,如下所示:
var resourceSchema = new Schema({
_id: { type: Number },
firstname: { type: String, display:'First name' },
lastname: { type: String, display:'Last name' }
});
mongoose.model('resources', resourceSchema);
So basically I can retrieve this symmetrically on angular side and I have all I need to map the fields and display them nicely. It seems I can also describe the validation but I'm not there yet.
所以基本上我可以在有角度的一侧对称地检索这个,我有我需要的一切来映射字段并很好地显示它们。似乎我也可以描述验证,但我还没有。
Any constructive feedback on this approach (whether it is valid or totally heretic) is appreciated.
对这种方法的任何建设性反馈(无论是有效的还是完全异端的)表示赞赏。