2014-10-30 58 views
0

如何根據另一個非JS Angular文件中的全局變量更新Angular $ scope變量?我正在使用jQuery插件來生成一些值。我想將此值連接到我的控制器中的$ scope變量。然而,這個值是不斷變化的,我不認爲我的$ scope變量會自動更新並修改非Angular變量。什麼是這樣做的好方法?謝謝!

+0

沒有..它不會..我想你有一個選擇是使用具有與全局變量值 – 2014-10-30 02:56:01

+0

更新範圍變量@ArunPJohny可以使用間隔基礎的解決方案$ watch的功能形式來實現這一點。詳情請參閱我的回答。 – metacubed 2014-10-30 02:58:55

+0

@metacubed然後當值被改變時誰會觸發摘要循環... – 2014-10-30 03:01:14

回答

1

通過將函數包裝到全局變量中,您可以使用$watch。內部控制的link功能,補充一點:

$scope.$watch(
    function() { 
     return globalVar; 
    }, 
    function(newValue, oldValue) { 
     // Global var changed! Do stuff. 
     $scope.scopeVar = newValue; 
    }); 

AngularJS不斷輪詢或檢查的第一個函數的返回值,返回全局變量。這是每個消化循環多次完成的。

當值更改時,它會調用第二個函數,它是更改的事件處理函數。您可以在此處添加用於處理更改的邏輯。爲了方便起見,更改處理程序將傳入舊值和新值。

在這種情況下,我只是設置一個範圍變量與改變的全局值。

+0

看看http://jsfiddle.net/arunpjohny/Lfz8bo11/2/ - 如果你保持理想什麼都沒有發生......但只有當你點擊按鈕變量更新 – 2014-10-30 03:06:46

+0

@ArunPJohny右..沒有什麼否則觸發摘要。 – metacubed 2014-10-30 03:11:32

0

如果全局變量在angujarjs之外更新,一個可能的解決方案是@metacubed提出的問題,但它有一個問題,即如果沒有由其他操作執行的摘要循環,變量將不會更新... http://jsfiddle.net/arunpjohny/Lfz8bo11/2/

所以另一種解決方案,我可以建議是使用間隔爲基礎的方法(它可以是因爲循環的消化恆定處決昂貴)等

var app = angular.module('my-app', [], function() {}) 
 

 
app.controller('AppController', function($scope, $interval) { 
 
    $scope.mycounter = counter; 
 

 
    $interval(function() { 
 
    $scope.mycounter = counter; 
 
    }, 1000); 
 

 
    $scope.something = function() {} 
 
}) 
 

 
var counter = 0; 
 
setInterval(function() { 
 
    counter++; 
 
}, 500);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="my-app" ng-controller="AppController"> 
 
    {{mycounter}} 
 
    <button ng-click="something()">Do something</button> 
 
</div>

+0

當,如果它真的太昂貴,那麼也許我應該通過無角度的js文件處理我的變量,並使用jQuery顯示它.... – pyramidface 2014-10-30 03:36:14

+0

如果您可以控制誰在更新值....那麼你可以考慮一個自定義的jQuery事件,然後你可以使用一個指令 – 2014-10-30 03:39:16

+0

現在,我有我的jQuery的方式來工作。該值只是附加到跨度。你說我可以使用一個角度指令來觀察這個跨度的內容並更新,因爲這個附加值正在改變(jQuery空白+附加)? – pyramidface 2014-10-30 03:43:47

0

間隔解決方案似乎工作,但作爲@ Arun-p-johny說,可能有很多性能成本,

我建議另一種方法,解決:'調用範圍的挖掘機週期只有當變量的變化

jsfiddle

var updateDigest = function(){ 
    var appElement = document.querySelector('[ng-app=my-app]'); 
    var appScope = angular.element(appElement).scope(); 
    var controllerScope = appScope.$$childHead; 
    controllerScope.$digest(); 
}; 

var counter = 0; 
setInterval(function() { 
    counter++; 
    updateDigest(); 
}, 500); 

看到這個answer

這是工作的,第一孩子是你正在使用的範圍。(喲你的應用程序不可能是這樣的),所以可能需要一個解決方法,讓rootcope(eg. jsfiddle)在rootscope中發射或設置一個變量。

或者我會推薦一個更好的和優雅的解決方案..把外部庫帶到角上下文(創建一個包裝),似乎對我來說是更好的解決方案。

var app = angular.module('my-app', [], function() {}) 
 

 
app.controller('AppController', function($scope, $rootScope) { 
 
    $scope.mycounter = counter; 
 

 
    $rootScope.$on('updateOuter', function(e, d) { 
 
    console.log('d', d); 
 
    $scope.mycounter = d; 
 
    $scope.$apply(); 
 
    }); 
 

 
    $scope.something = function() {} 
 
}); 
 

 
var updateDigest = function(param) { 
 
    var appElement = document.querySelector('[ng-app=my-app]'); 
 
    var appScope = angular.element(appElement).scope(); 
 
    var rootScope = appScope; 
 
    rootScope.$emit('updateOuter', param); 
 
}; 
 

 
var counter = 0; 
 
setInterval(function() { 
 
    counter++; 
 
    updateDigest(counter); 
 
}, 500);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"> 
 
</script> 
 

 
<body ng-app="my-app"> 
 
    <div id="container" ng-controller="AppController"> 
 
    {{mycounter}} 
 
    </div> 
 
</body>