![](/img/trans.png)
[英]How to change a $scope variable outside the controller in angularjs
[英]How to change AngularJS data outside the scope?
經過幾個小時令人沮喪的搜索后,我覺得我需要在這里提交我的問題。 如果這個問題在某種程度上得到了回答,我提前道歉,但到目前為止我的搜索都沒有幫助。 所以這是我的問題:
我的JavaScript代碼正在創建一個由AngularJS修改和監視的對象。 在某些事件上(比如加載對象的先前設置),我希望從范圍外部更改此對象的屬性。 問題是輸入沒有改變......
以下是我希望如何執行這些更改的示例:
HTML代碼:
<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代碼:
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;
}
當我現在按“更改為20”按鈕時,沒有任何反應。 如何從change
功能修改此人的年齡?
⚠️ 警告:此答案陳舊,未反映最佳做法,可能與較新版本的Angular不兼容。
MaxPRafferty的答案是正確的 - 在范圍內使用函數通常是更好的方法 - 但還有另一種選擇。 您可以使用angular.element(...).scope()
方法從不相關的JavaScript訪問Angular范圍。 通過定位具有指定ng-app
屬性的元素來選擇應用程序的頂級范圍,例如點擊處理程序中的內容:
function change() {
var appElement = document.querySelector('[ng-app=myApp]');
var $scope = angular.element(appElement).scope();
$scope.$apply(function() {
$scope.data.age = 20;
});
}
在這個小提琴中嘗試一下。
Shaun 剛剛指出 Angular只會在$digest()
調用期間處理任何“監視”或“綁定”。 如果您只是直接修改$scope
的屬性,則可能不會立即反映更改,您可能會遇到錯誤。
要觸發這個,你可以調用$scope.$apply()
來檢查臟范圍並更新任何正確綁定的東西。 傳遞一個在$scope.$apply
內執行工作的函數$scope.$apply
將允許Angular捕獲任何異常。 Scope的文檔中解釋了此行為。
Jeremy的回答非常好,雖然現在Angular已經改變了,並且將不再有效,除非你添加這行代碼:
$scope = $scope.$$childHead;
因此,更改的函數應如下所示
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;
});
}
http://jsfiddle.net/MaxPRafferty/GS6Qk/
您希望將ng-click屬性設置為范圍中的函數,如下所示:
var person = {
age: 16
};
// Create module
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return person;
});
function FirstCtrl($scope, Data) {
$scope.data = Data;
$scope.update = function(){
$scope.data.age = 20;
}
}
使用Jeremy Banks的完美答案,在一行中完成,雖然我引用了控制器與應用程序:
angular.element('[ng-controller=myController]').scope().$apply(function(x){ x.foo = "bar"; });
只需使用短暫的$ timeout
var whatever = 'xyz';
$timeout(function(){
$scope.yourModel.yourValue = whatever;
}, 0);
你完成了
我之前嘗試過來自www周圍的所有那些$ apply hacks,它們都沒有用。 但是這個$ timeout在每種情況下總是像魅力一樣。 您所需要的只是$ scope和$ timeout的引用。
Wy及其工作原理:
// Imagine an angular buildin-function
angular.$queue = function(fn){
$timeout(fn, 0);
}
它基本上像一個隊列。 但要注意它是異步的。
當在指令之外修改了值時,ng-model指令調用$ render方法。 通過讀取$ viewValue屬性獲取新值。 看: https : //jsfiddle.net/cesar_ade/g5ybs6ne/
ctrl.$render=function(){
setSelected(ctrl.$viewValue || 'Not Sure');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.