我有一组窗口变量,我想绑定到AngularJS中的范围变量。
到目前为止,这是我的代码,但它不起作用:
.directive('watchGlobals', function() {
return {
link: function(scope, element, attrs) {
var watchGlobals = attrs.watchGlobals.split(',');
for (var i = 0; i < watchGlobals.length; i++) {
scope[watchGlobals[i]] = window[watchGlobals[i]];
}
}
}
});
这样做的最佳方法是什么?我试图避免使用setInterval。我想在更新窗口变量时更新范围。有没有办法可以在AngularJS中观察窗口变量?
答案 0 :(得分:2)
使用简单的js pubsub(例如PubSubJs),您可以在角度内订阅服务。另一个应用程序应该通过pubsub发布,这将调用服务中的调用。该服务将更新角度应用程序。
angular.factory('connectService', ['$rootScope', function($rootScope) {
var token = PubSub.subscribe( 'TOPIC_NAME', function(msg, data) {
$rootScope.$apply(function() {
$rootScope.$broadcast('TOPIC_NAME', { msg: msg, data: data });
});
});
}]);
从其他应用中,您现在可以发布数据:
PubSub.publish( 'MY TOPIC', 'hello world!' );
现在,只要您想要以角度使用方式获取数据:
$scope.$on('TOPIC_NAME', function(data) {
console.log(data.msg, data.data); // do whatever you want to do with the data
});
答案 1 :(得分:1)
正如评论所说,有很多方法可以做到这一点,推送数据可能比听取数据更好。
您可以使用简单的钩子角度来简单地调用现有指令范围内的$digest
。然后,不要像当前那样观察变量值,而是使用函数返回window属性的当前值。这样,如果值是简单类型(字符串,数字)或被替换,则不会丢失监视:
/*** angular code ***/
angular.module('myApp', [])
.controller('ctrl', function() {})
// inject the standard angular $window service (really just the window object)
.directive('watchGlobals', function($window) {
return {
link: function(scope, element, attrs) {
// add a method to the raw DOM element that JS can call to update the scope
element[0].externalUpdate = function() {
scope.$digest();
};
var watchGlobals = attrs.watchGlobals.split(',');
// loop as before, but use an IIFE to isolate the variable name
for (var i = 0; i < watchGlobals.length; i++) {
(function(variable) {
scope.$watch(function() { return $window[variable]; }, // use a function
function(newVal) { scope[variable] = newVal; }); // update scope
})(watchGlobals[i]);
}
}
}
});
/*** JS code ***/
// global function to update angular scope
function updateAngular() {
// find the directive element and call it's externalUpdate() function
// this is the only "bit in the middle" of the 2 apps
document.getElementById('angular-hook').externalUpdate();
// alternative option, but breaks with $compileProvider.debugInfoEnabled(false)
//angular.element(document.getElementById('angular-hook')).scope().$digest();
}
function setValueX() {
window.xVal = document.getElementById('valX').value;
updateAngular();
}
function setValueY() {
window.yVal = document.getElementById('valY').value;
updateAngular();
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h2>Angular</h2>
<div ng-app="myApp">
<div ng-controller="ctrl">
<div id="angular-hook" watch-globals="xVal,yVal"></div>
<p>x: {{xVal}}</p>
<p>y: {{yVal}}</p>
</div>
</div>
<h2>JS</h2>
<p>X: <input type="text" id="valX" /> <button onclick="setValueX()">Set</button></p>
<p>Y: <input type="text" id="valY" /> <button onclick="setValueY()">Set</button></p>
UPDATE:将scope().$digest()
调用更改为DOM元素函数以解决debugInfo问题。