I'm using ui-bootstrap to handle my modals. I'm passing $scope in as the scope parameter, it looks something like this:
var modalInstance = $modal.open({
templateUrl: 'views/pages/gethelp/modals/bulk_change.html',
controller: BulkChangeCtrl,
size: 'lg',
scope: $scope,
backdrop:"static",
resolve: {
type: function() { return type; },
field:function() { return field; },
preset: function() { return preset; }
}
});
Inside my modal controller, I'm defining a single model string value that I want to both bind to inputs as well as use as the selected value when the user hits submit. This is simple and is setup like:
$scope.val = "";
Yet, in my submit function that's called via a button click, no matter what, $scope.val is empty. It's like the functions are referencing a completely different version of $scope.val. Yet in my view, I can bind to {{val}} no problem.
Why is this? When I update my code to be something like:
$scope.obj = { val:"" };
It all works as expected and I can bind to {{obj.val}}. What am I completely missing here?
It is because bootstrap creates a child scope (@var modalScope = (modalOptions.scope || $rootScope).$new();
) of provided scope with scope argument. So in angular child scopes prototypical inherit from the parent. And primitive types (when there is no .
in the binding) will not be consulted for in the prototype chain and will add a new property val
and update it which will not be reflected in the underlying scope, only updates to reference types will (object, function reference etc..) have the changes reflected and hence obj.val
works since the parent scope also has reference to the same obj
.
So when you do:-
$scope.val = "";
new child scope created out of the provided scope will update val
at the child since it is not updated as a value on a reference type, you wont see it updated at its parent .
Here is a good read