Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
192 views
in Technique[技术] by (71.8m points)

javascript - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...