Reputation: 4440
I am attempting to slightly reduce the clutter of $scope
in my angular application, pursuant to several tutorials on the subject. One such article demonstrates a good tactic for cleaning up $scope
is to instead make my controllers 'classes', so to speak. Like this;
//Don't do this
app.controller('MyCtrl', function($scope){
$scope.doStuff = function(){
//Really long function body
};
});
//Do this instead
var MyCtrl = function($scope){
var _this = this;
_this.doStuff = function(){
_this.doStuff();
};
};
I am attempting to do this, but am having a great deal of trouble - as it seems that code attached to _this
is completely different than code attached to $scope
. For instance;
var editor = function($scope){
var _this = this;
_this.Model = {
Id: null,
Editing: false
};
_this.options = {
columns : [
{ field: "Id", width: 25, title: "Identity" },
{ field: "Name", width: 40, title: "Name" }
]
};
};
And then attempting to use this in directives ...
var gridDirective = function($parse) {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attributes, controller) {
// I expected this line to output the array I made, but it comes up undefined
console.log('scope.options: ', scope.options);
}
}
};
I expected the objects I assigned to _this
to be available on the scope
in the directive, but this doesn't happen. It is only when I directly, explicitly assign them to $scope
do I see them show up in a directive.
Is there any solution to this? Or do I just have to use $scope
everywhere?
Upvotes: 0
Views: 1717
Reputation: 4611
In your case, if you want achieve using this
instead of $scope
, you should do it like this:
var editor = function($scope){
var _this = $scope;
_this.Model = {
Id: null,
Editing: false
};
_this.options = {
columns : [
{ field: "Id", width: 25, title: "Identity" },
{ field: "Name", width: 40, title: "Name" }
]
};
};
But this approach doesn't make sense. The article suggestion is (and in my opinion also)
for controllers use constructor pattern what does it mean? and what the advantages of that, you will have private which you can not assign to scope and you will have functions which will be assigned to scope by your choose, this will be keep your controller cleaner. Example from this article I think is not right, it should be like this:
var MyCtrl = function($scope){
var _this = this;
$scope.doStuff = _this.doStuff;
};
MyCtrl.prototype.doStuff = function(){
//Really long function body, also this bounded with scope
};
MyCtrl.prototype.anotherFunc= function(){
//This is another function which not bounded to scope
};
UPDATE
I would like to suggest read this article in this article explained styleguide for angular.
Upvotes: 1
Reputation: 30098
You can access these properties in the alias that you have provided in the ng-controller
as notation within the scope of the controller's context. So if you're declaring the controller like this:
ng-controller="EditorController as editor"
this means that you can access the editor properties within the $scope.editor
property.
Javscript
.controller('EditorController', function() {
var _this = this;
_this.Model = {
Id: null,
Editing: false
};
_this.options = {
columns : [
{ field: "Id", width: 25, title: "Identity" },
{ field: "Name", width: 40, title: "Name" }
]
};
})
.directive('grid', function($parse) {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attributes) {
// I expected this line to output the array
// I made, but it comes up undefined
console.log(scope.editor.options);
}
}
});
HTML
<div ng-app="demo" ng-controller="EditorController as editor">
<div grid></div>
</div>
UPDATE
Since your directive is already defined with an isolated scope, you better make use of defining the properties and accessing the objects assigned from it, rather than accessing them from the parent scope.
JAVASCRIPT
.directive('grid', function($parse) {
return {
restrict: 'A',
scope: {
options: '='
},
link: function(scope, element, attributes) {
console.log(scope.options);
}
}
});
HTML
<div ng-app="demo" ng-controller="EditorController as editor">
<div grid="editor.options"></div>
</div>
You can learn more about isolate scopes and directives in the $compile
service.
Upvotes: 1
Reputation: 20014
$scope
needs to be set to _this
instead of just this
or this
to local var at controller level.
A quick sample demo:
app.controller('MainController', function(){
var vm = this;
vm. error = '';
vm.onUserComplete = function(response){
console.log(vm.error);
};
});
John Papa had recommended an approach where you could create Controllers methods using this
. However, I personally I do see the benefit of deviating from the standard but if you want to read more about this approach here is the article that explains it:
http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/
Upvotes: 1