2014-10-30 36 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>