admin管理员组文章数量:1327320
I'm trying to use some of angulars best practices defined on the google-styleguide site: .html
But at the moment I'm struggling with some issues. Before I used this styleguide I had the $scope
variable available to do a $watch
on a variable for instance.
app.controller('myController',['$scope', function($scope) {
$scope.$watch('myVariable', function(val) {
alert("I'm changed");
});
}]);
Now with my new approach I don't know how to handle this? Should I still inject $scope
? Because I do not have to inject $scope
when I'm not using $watch
.
function myController($scope) {
var vm = this;
vm.myVariable = "aVariable";
vm.$watch('vm.myVariable', function(val) {
// error because $watch is undefined
});
//$scope.$watch - works
}
app.controller('myController',['$scope', myController]);
The styleguide also advices to make use of prototypes. But what if I had to inject a service? What is the best approach to use a service inside your prototype?
function myController(MyService) {
var vm = this;
vm.myService = MyService;
}
myController.prototype.callService = function() {
var vm = this;
vm.myService.doSomething();
}
Is this correct? Or am I missing something, is there a place where I can find more information about this style of angular programming?
In my opinion it feels more like natural javascript and I want to use this way of organizing my AngularJS apps.
Thanks in advance
Update
For the 'service' problem I was thinking of something as follows:
function MyBaseController(AService, BService, CService) {
this.aService = AService;
this.bService = BService;
this.cService = CService;
}
function myController() {
var vm = this;
MyBaseController.apply(vm, arguments);
}
myController.prototype.doSomething() {
var vm = this;
this.aService.somethingElse();
}
But this doesn't feel right imo..
I'm trying to use some of angulars best practices defined on the google-styleguide site: https://google-styleguide.googlecode./svn/trunk/angularjs-google-style.html
But at the moment I'm struggling with some issues. Before I used this styleguide I had the $scope
variable available to do a $watch
on a variable for instance.
app.controller('myController',['$scope', function($scope) {
$scope.$watch('myVariable', function(val) {
alert("I'm changed");
});
}]);
Now with my new approach I don't know how to handle this? Should I still inject $scope
? Because I do not have to inject $scope
when I'm not using $watch
.
function myController($scope) {
var vm = this;
vm.myVariable = "aVariable";
vm.$watch('vm.myVariable', function(val) {
// error because $watch is undefined
});
//$scope.$watch - works
}
app.controller('myController',['$scope', myController]);
The styleguide also advices to make use of prototypes. But what if I had to inject a service? What is the best approach to use a service inside your prototype?
function myController(MyService) {
var vm = this;
vm.myService = MyService;
}
myController.prototype.callService = function() {
var vm = this;
vm.myService.doSomething();
}
Is this correct? Or am I missing something, is there a place where I can find more information about this style of angular programming?
In my opinion it feels more like natural javascript and I want to use this way of organizing my AngularJS apps.
Thanks in advance
Update
For the 'service' problem I was thinking of something as follows:
function MyBaseController(AService, BService, CService) {
this.aService = AService;
this.bService = BService;
this.cService = CService;
}
function myController() {
var vm = this;
MyBaseController.apply(vm, arguments);
}
myController.prototype.doSomething() {
var vm = this;
this.aService.somethingElse();
}
But this doesn't feel right imo..
Share Improve this question edited Mar 28, 2014 at 8:12 Dieterg asked Mar 25, 2014 at 10:20 DietergDieterg 16.4k3 gold badges33 silver badges50 bronze badges 8- Great question! For your question about the $watch, I'm wondering if the style guide is trying to avoid calling $watch within a controller since they state "Controllers are classes." Since you know when data is changing within a controller, could it be that your "$watch" is executed when a specific method is called within the controller? – Pete Commented Mar 27, 2014 at 13:50
-
Actually I want to do a
$watch
on a variable that's getting changed inside a directive. I think there wouldn't be a problem when you change a variable inside a method. The, let's call it scope, will get updated anyway. – Dieterg Commented Mar 27, 2014 at 13:55 - 1 In a directive, you can access scope from Link, Compile, and Controller, so $watch is accessible in those cases. – Pete Commented Mar 27, 2014 at 14:00
- But how do I check for updates in my controller? I know I can $watch a variable inside my directive. But how do I reflect these changes to my controller? Normally I would do an $apply in my directive and afterwards I would $watch for a change inside my controller. – Dieterg Commented Mar 27, 2014 at 14:03
- 2 I don't think you should be changing the controller variable within the directive because then the view is modifying the model. The directive, should pass mands to the controller, so you would know when the variable is changed. Otherwise, if you need to, you could have the directive-controller fire an event that the controller is listening to and then process the change. – Pete Commented Mar 27, 2014 at 14:07
2 Answers
Reset to default 7 +50It is perfectly valid to inject $scope to get access to things like $watch even when your using the "controller as" syntax. For example:
JS
var MyController = function($scope) {
$scope.$watch('ctrl.someVar' function() {
...
});
this.someVar = 123;
}
MyController.$inject = ['$scope'];
HTML
<div ng-controller="MyController as ctrl">
....
</div>
The first example you gave of injecting a service into a controller is good. For the inheritance example I would do something like this.
var BaseController = function(AService, BService) {
this.aService = AService;
this.bService = BService;
}
BaseController.prototype.doSomethingWithAAndB = function() {
...
}
var MyController = function(AService, BService, CService) {
BaseController.call(this, AService, BService);
this.cService = CService;
}
MyController.$inject = ['AService', 'BService', 'CService'];
//Note: you'll need to add a polyfill for Object.create if you want to support ES3.
MyController.prototype = Object.create(BaseController.prototype);
If you find it is too cumbersome to specify all the parameters in the child controller you could always just inject $injector
and pass that up to your base controller.
@rob answer is correct. There are perfectly valid reasons to still want $scope
injected in your controllers, $watch
$on
$emit
$broadcast
to name a few. Sure you can get away with this requirement in some cases using directives or services, but it's not always worth the time or plexity.
I've given the controller as
syntax a go, but found that in most of my use cases I still had a dependency on $scope
in my controllers. I disliked this and so I ended up with the following convention:
var MyController = function($scope) {
$scope.vm = {};
var vm = $scope.vm;
vm.propA = 1;
vm.propB = 2;
vm.funcA = function(){};
$scope.$watch('vm.propA' function() {
});
}
So it uses the 'old school' approach but with a new school feel. Everything in the view hangs off vm
.
本文标签: javascriptAngularJS best practicesStyleguideStack Overflow
版权声明:本文标题:javascript - AngularJS best practices - Styleguide - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742200644a2431894.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论