I’m trying to keep my controllers as thin as possible, so I keep my domain logic in services and factories.
When I need to call a function in response to a user action like a click I assign the factory or service’s function to the controller’s $scope
variable.
$scope.saveStuff = myFactory.SaveStuff;
myFactory.SaveStuff
actually calls a bunch of private functions that $scope
can’t see. I was a little surprised that a call to $scope.saveStuff
didn’t result in a bunch of reference errors.
How does this work? Is $scope.saveStuff
just a function pointer to myFactory.SaveStuff
? Does this mean that $scope.saveStuff
is actually executing inside the scope of myFactory
so it has access to any private data/functions inside myFactory
?
Are you familiar with JavaScript closures? The function closes over the other functions so it retains memory of them when you call them in your controller or link function.
Consider this:
function publicOne() {
var x = { val: 5 }
publicTwo(x);
console.log(x);
}
function publicTwo(obj) {
_privateOne(obj);
function _privateOne(v) {
obj.val++
}
}
Here, publicOne
calls publicTwo
, but _privateOne
is private to publicTwo
. Nonetheless, it gets called within the context of publicOne
because it closes over the _privateOne
function.
In Javascript, functions are objects. Function
objects.
As objects they can be referenced by variables. That’s pretty much what we do with $scope.myFunction = function()..
.
So, basically what you are doing is referencing the factory function from the scope var. Here, $scope is tunneling the function, instead of abstracting it. You are then coupling $scope’s “interface” to the factory’s “interface”.
Does this mean that
$scope.saveStuff
is actually executing inside the
scope ofmyFactory
so it has access to any private data/functions
insidemyFactory
?
No, it only means that your view is triggering the factory. $scope remians unaware of the factory’s implementation details. Everything encapsulated within the Factory is scoped as local and remains local to the factory whether its public functions are referenced by 3rd members or not.
Same applies to the function saveStuff
. It has its own local scope that it’s not visible by $scope
.
Unless you expose the private methods, the $scope and hence the view and the model wont have access to them.