AngularJS 通过源标记动态加载普通 Javascript

AngularJS Dynamically Loading Plain Old Javascript Through Source Tag

我正在尝试使用 AngularJS promises 动态加载一些 javascript。

HTML 文件(index.html)

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular-route.js"></script>
    <script type="text/javascript" src="main.js"></script>

    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body ng-app="main">

<ng-view></ng-view>

</body>
</html>

AngularJS文件(main.js)

angular.module('main', ['ngRoute'])
    .config(function($routeProvider) {
        $routeProvider
            .when('/',
            {
                controller: 'MainCtrl',
                templateUrl: 'partial.html',
                resolve: {
                    temp: MainCtrl.testFn
                }
            })
            .otherwise({
                redirectTo: '/'
            })
    })

MainCtrl = angular.module('main')
    .controller('MainCtrl', function () {

    });

angular.module('main')
    .factory('MyFactory', function($q) {
        data = {
            loadJS: function() {
                var deferred = $q.defer()
                var script = document.createElement('script');
                script.type = 'text/javascript'
                script.src = 'https://apis.google.com/js/client.js'
                script.onload = function() {
                    deferred.resolve('Google Client Library loaded')
                }
                document.body.appendChild(script)
                return deferred.promise
            }
        }
        return data
    })

MainCtrl.testFn = function($log, MyFactory) {
    return MyFactory.loadJS().then(function(result) {
        $log.debug(result)
        gapi.client.load()
    })
}

调用了 onload 方法(因为 promise 已解决并打印了调试行),但由于在 gapi 上未找到客户端属性而引发错误(未捕获类型错误:无法读取属性 'load'未定义)。

我错过了什么?有没有人有更好的方法用 Angular promises 动态加载 JS(仅使用 Angular 和 JS)?

只需加载内容并使用 eval(data) 计算 Javascript。 标签不会被处理,因为它是在页面加载后生成的。

我想,脚本正在成功加载,但 gapi.client 无法立即使用。您需要为此目的(某些全局函数)向 google api url 提供处理程序。

angular.module('app', [])

.controller('mainCtrl', function(googleClientLoader) {
  googleClientLoader.load().then(
    function() {
      console.debug(gapi.client);
    }
  )
})

.factory('googleClientLoader', function($q) {
  return {
    load: function() {
      var deferred = $q.defer()
      var script = document.createElement('script');
      script.type = 'text/javascript'
      script.src = 'https://apis.google.com/js/client.js?onload=handleClientLoad';
      window.handleClientLoad = function() {
        deferred.resolve('Google Client Library loaded');
      }
      document.body.appendChild(script)
      return deferred.promise;
    }
  }
})