Ciel Ciel - 1 month ago 6
AngularJS Question

angularjs - difficulty replacing "$scope" with "this" and similar

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?

Answer

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.

DEMO

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.

Comments