Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change AngularJS data outside the scope?

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?

like image 739
birgersp Avatar asked Jul 15 '13 14:07

birgersp


People also ask

Does AngularJS support scope inheritance?

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.

What is $scope in AngularJS?

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).

What is the difference between $scope and scope in AngularJS?

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.

How do I move data from one page to another in AngularJS?

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.


2 Answers

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;     }); } 
like image 23
Aleksandrus Avatar answered Oct 12 '22 20:10

Aleksandrus


⚠️ 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.

like image 133
Jeremy Avatar answered Oct 12 '22 21:10

Jeremy