我的角度控制器设置与文档中显示的大多数示例类似,因此它是一个全局函数。我假设当角度引擎在html中看到控制器标记时,正在调用控制器类。
我的问题是我想将一个参数传递给我的控制器,我不知道该怎么做,因为我没有初始化它。我看到一些建议使用ng-init的答案。但我的参数不是一个简单的字符串 - 它是一个复杂的对象,由我的js的另一个(非角度)部分加载。它也无法在加载时使用,但需要一段时间才能出现。
所以我需要一种方法将这个对象,当它最终完成加载时,传递到控制器(或范围),以便控制器可以与它进行交互。 这可能吗?
答案 0 :(得分:8)
您可以使用服务或工厂,并结合承诺:
您可以设置一个返回承诺的工厂,并创建一个全局函数(可从第三方JS访问)来解决这个承诺。
请注意$rootScope.$apply()
来电。 Angular不会调用承诺的then
函数,直到$apply
个循环。请参阅$q
docs。
app.factory('fromoutside', function($window, $q, $rootScope) {
var deferred = $q.defer();
$window.injectIntoAngularWorld = function(obj) {
deferred.resolve(obj);
$rootScope.$apply();
};
return deferred.promise;
});
然后在您的控制器中,您可以请求fromoutside
服务并在数据到达时绑定到该数据:
app.controller('main', function($scope, fromoutside) {
fromoutside.then(function(obj) {
$scope.data = obj;
});
});
然后在Angular之外的某个地方:
setTimeout(function() {
window.injectIntoAngularWorld({
A: 1,
B: 2,
C: 3
});
}, 2000);
就个人而言,我觉得这比通过DOM进入Angular控制器更清晰。
Mark Rajcok在评论中询问是否可以修改此数据以允许多次获取数据。
现在,多次获取数据可能意味着增量更新,或更改对象本身或其他内容。但是需要做的主要事情是将数据导入Angular世界,然后获得正确的角度范围来运行他们的$digest
。
In this fiddle,当您从角度以外获取数组更新时,我已经展示了一种方式。
它使用与上述承诺示例类似的技巧。
这是主要的工厂:
app.factory('data', function($window) {
var items = [];
var scopes = [];
$window.addItem = function(item) {
items.push(item);
angular.forEach(scopes, function(scope) {
scope.$digest();
});
};
return {
items: items,
register: function(scope) { scopes.push(scope); }
};
与前面的示例一样,我们将一个函数附加到$window
服务(全局公开)。新位暴露了register
函数,需要更新data
的控制器应该用来注册自己。
当外部JS调用angular时,我们只是遍历所有已注册的作用域并在每个作用域上运行摘要以确保它们已更新。
答案 1 :(得分:5)
在非角度JavaScript中,您可以访问与DOM元素关联的范围,如下所示:
angular.element(someDomElement).scope().someControllerFunction(delayedData);
我假设您可以使用jQuery选择器或其他东西找到someDomElement。