After hours of frustrating searches I feel I need to submit my question here. I apologize in advance if this question is somehow answered before but none of my searches has helped so far. So here's my question:
My JavaScript code is creating an object, which is modified and monitored by AngularJS. On some events (like loading a previous setting of the object), I wish to change the properties of this object from outside the scope. The problem is that the inputs does not change...
Here's an example of how I wish to perform these changes:
HTML code:
<div ng-app="myApp" ng-controller="FirstCtrl"> <input type="number" ng-model="data.age"> <h1>{{data.age}}</h1> <input type="button" value="Change to 20" ng-model="data" onclick="change()">
JavaScript Code:
var person = { age: 16 }; // Create module var myApp = angular.module('myApp', []); myApp.factory('Data', function() { return person; }); function FirstCtrl($scope, Data) { $scope.data = Data; } function change() { person.age = 20; }
When I now press the "Change to 20" button, nothing happens. How can I modify the person's age from the change
function?
The $scope object used by views in AngularJS are organized into a hierarchy. There is a root scope, and the $rootScope can has one or more child scopes.
The $scope in an AngularJS is a built-in object, which contains application data and methods. You can create properties to a $scope object inside a controller function and assign a value or function to it. The $scope is glue between a controller and view (HTML).
The $ in "$scope" indicates that the scope value is being injected into the current context. $scope is a service provided by $scopeProvider . You can inject it into controllers, directives or other services using Angular's built-in dependency injector: module.
To save the data that you want to transfer to another $scope or saved during the routing, you can use the services ( Service ). Since the service is a singleton , you can use it to store and share data. Look at the example of jsfiddle. Showing using variable in different controller jsfiddle.
Jeremy's answer is really good, though now Angular has changed, and will no longer work, unless you add this line of code:
$scope = $scope.$$childHead;
So, the changed function should look like this
function change() { var appElement = document.querySelector('[ng-app=myApp]'); var $scope = angular.element(appElement).scope(); $scope = $scope.$$childHead; // add this and it will work $scope.$apply(function() { $scope.data.age = 20; }); }
⚠️ Warning: This answer is old, does not reflect best practices, and may not be compatible with newer versions of Angular.
MaxPRafferty's answer is correct - using a function in the scope is often the nicer way to do this - but there is another option. You can use the angular.element(...).scope()
method to access an Angular scope from unrelated JavaScript. Select the top-level scope for the app by targeting the element that has the ng-app
attribute specified, with something like in your click handler:
function change() { var appElement = document.querySelector('[ng-app=myApp]'); var $scope = angular.element(appElement).scope(); $scope.$apply(function() { $scope.data.age = 20; }); }
Try it out in this Fiddle.
Shaun just pointed out that Angular will only process any "watches" or "bindings" during a $digest()
call. If you just modify the properties of the $scope
directly, the changes may not be reflected immediately and you may gets bugs.
To trigger this you can call $scope.$apply()
which will check for dirty scopes and update anything bound correctly. Passing a function that does the work inside $scope.$apply
will allow Angular to catch any exceptions as well. This behaviour is explained in the documentation for Scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With