angularjs将变量传递给控制器

VBA*_*ole 2 javascript angularjs

我的角度控制器设置与文档中显示的大多数示例类似,因此它是一个全局函数.我假设当角度引擎在html中看到控制器标记时,正在调用控制器类.

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

所以我需要一种方法来传递这个对象,当它最终完成加载时,进入控制器(或范围),以便控制器可以与它进行交互.这可能吗?

sat*_*run 8

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

您可以设置一个返回promise的工厂,并创建一个全局函数(可从第三方JS访问)来解析promise.

记下$rootScope.$apply()电话.Angular then$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;
});
Run Code Online (Sandbox Code Playgroud)

然后在您的控制器中,您可以请求fromoutside服务并在数据到达时绑定到数据:

app.controller('main', function($scope, fromoutside) {
    fromoutside.then(function(obj) {
        $scope.data = obj;
    });
});
Run Code Online (Sandbox Code Playgroud)

然后在Angular之外的某个地方:

setTimeout(function() {
    window.injectIntoAngularWorld({
        A: 1,
        B: 2,
        C: 3
    });
}, 2000);
Run Code Online (Sandbox Code Playgroud)

这是一个小提琴.

就个人而言,我觉得这比通过DOM进入Angular控制器更清晰.

编辑:另一种方法

Mark Rajcok在评论中询问是否可以对其进行修改以允许多次获取数据.

现在,不止一次获取数据可能意味着增量更新,或更改对象本身或其他内容.但是需要做的主要事情是将数据导入Angular世界,然后获得正确的角度范围来运行他们的$digests.

在这个小提琴中,我已经展示了一种方法,当你可能只是从角度以外获得一个数组的更新.

它使用与上面的承诺示例类似的技巧.

这是主要的工厂:

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); }
};
Run Code Online (Sandbox Code Playgroud)

与前面的示例一样,我们将一个函数附加到$window服务(全局公开).新位暴露了一个register函数,需要更新的控制器data应该用来注册自己.

当外部JS调用angular时,我们只是遍历所有已注册的作用域并在每个作用域上运行摘要以确保它们已更新.


Mar*_*cok 5

在非角度JavaScript中,您可以访问与DOM元素关联的作用域,如下所示:

angular.element(someDomElement).scope().someControllerFunction(delayedData);
Run Code Online (Sandbox Code Playgroud)

我假设您可以使用jQuery选择器或其他东西找到someDomElement.