2

我有我的角度控制器设置,就像文档中显示的大多数示例一样,它是一个全局函数。我假设当角度引擎在 html 中看到控制器标签时,控制器类被调用。

我的问题是我想将一个参数传递给我的控制器,但我不知道该怎么做,因为我没有初始化它。我看到一些建议使用 ng-init 的答案。但我的参数不是一个微不足道的字符串 - 它是一个复杂的对象,正在由我的 js 的另一个(非角度)部分加载。它也不能在加载时使用,但需要一段时间才能出现。

所以我需要一种方法将这个对象在它最终完成加载时传递到控制器(或范围)中,以便控制器可以与之交互。这可能吗?

4

2 回答 2

8

您可以为此使用服务或工厂,并结合承诺:

您可以设置一个返回承诺的工厂,并创建一个全局函数(可从 3rd-party JS 访问)来解决承诺。

注意$rootScope.$apply()通话。thenAngular在一个$apply循环之前不会调用 Promise 的函数。请参阅$q文档

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 世界,然后获得正确的 Angular 范围来运行它们$digest的 s。

在这个 fiddle中,我展示了一种方法,当您可能只是从 angular 外部获取对 Array 的更新时。

它使用了与上面的 Promise 示例类似的技巧。

这是主要工厂:

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 时,我们只需遍历所有已注册的作用域并在每个作用域上运行摘要以确保它们已更新。

于 2013-02-19T00:11:09.013 回答
5

In your non-angular JavaScript, you can get access to the scope associated with a DOM element as follows:

angular.element(someDomElement).scope().someControllerFunction(delayedData);

I assume you can find someDomElement with a jQuery selector or something.

于 2013-02-18T21:16:26.213 回答