【问题标题】:Issues with google closure library and angularjsgoogle 闭包库和 angularjs 的问题
【发布时间】:2014-05-18 23:05:26
【问题描述】:

我正在重构我的ngTrader 游戏,按照angularjs-google-style 将我的所有控制器、服务、指令等...定义为类,并将函数定义为这些类的原型,然后用 Angular 注册类。

问题是让这些更改与闭包库的goog.provide()goog.require() 一起使用。使用下面的设置,我得到一个角度错误,上面写着

Failed to instantiate module ngTrader due to:
Error: [$injector:modulerr] Failed to instantiate module ngTrader.account due to:
Error: [ng:areq] Argument 'fn' is not a function, got undefined

Index.html

<body ng-app="ngTrader">
    ....
    <script src="bower_components/closure-library/closure/goog/base.js"></script>
    <script src="components/account/accountSrvc.js"></script>
    <script src="components/account/account.js"></script>
    <script src="app.js"></script>   
</body>

我尝试了这些文件的各种顺序,认为加载顺序会影响哪些可用,哪些不可用。我认为顺序应该无关紧要,因为这是 goog 提供/要求应该解决的问题。

  • app.js、account.js、accountSrvc.js
  • app.js、accountSrvc.js、account.js
  • accountSrvc.js、account.js、app.js

app.js

goog.provide('ngTrader');
goog.require('ngTrader.account');

ngTrader = angular.module('ngTrader', [ngTrader.account.name]);

account.js

goog.provide('ngTrader.account');
goog.require('ngTrader.account.accountSrvc');

ngTrader.account = angular.module('ngTrader.account', []);
ngTrader.account.service('accountSrvc', ngTrader.account.accountSrvc);

不确定我是否需要在此处调用goog.require(),谷歌风格并未将其包含在他们的 sn-p 中。我试过有和没有它。我也尝试在此处添加goog.require('ngTrader'),但这会引发错误,除非我将 app.js 移动为 index.html 中的第一个调用脚本,这反过来会引发有关未定义 ngTrader.account 的错误。

服务注册在此处按照 google 风格推荐服务示例显示将 module.service('request', hello.request.Request); 放入模块定义中。

accountSrvc.js

goog.provide('ngTrader.account.accountSrvc');

ngTrader.account.accountSrvc = function() {....};    
ngTrader.account.accountSrvc.prototype.reset = function() {....};

我在 accountSrvc.js 中放置了断点,并看到 ngTrader.account 对象添加了新的 accountSrvc 属性。但是当我检查 account.js 中的断点时,accountSrvc 属性是未定义的。

那么我哪里出了问题,加载脚本的顺序,我如何使用 require/provide 或其他什么?

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 我不是闭包专家,但这可能是缩小的问题。您可能需要明确定义对服务、控制器等的依赖项,因为 Angular 的依赖项注入使用参数名称来注入适当的依赖项。看看docs.angularjs.org/tutorial/step_05#a-note-on-minification
  • @GruffBunny 我已经在 yeoman 的角度生成器之上构建了它,这会在不会缩小代码的服务任务期间出现。

标签: javascript angularjs google-closure-library


【解决方案1】:

以下有帮助吗?

<body ng-app="ngTrader">
    <script src="bower_components/closure-library/closure/goog/base.js"></script>
    <script>
      goog.require("ngTrader");
    </script>
</body>

确保 js/libraries/goog/deps.js 中的路径已设置,如果没有,您可以使用 calcdeps 进行设置:

python \
 "/home/me/Software/Programming/JavaScript/Closure compiler/closure-library/closure/bin/calcdeps.py" \
 --path /var/www/html/hosts/site/public_html/js/libraries \
 --input /var/www/html/hosts/site/public_html/js/libraries/app.js \
 --output_mode deps \
 --output_file /var/www/html/hosts/gsa/public_html/js/libraries/goog/deps.js

文件的位置和名称可能很重要,因为 calcdeps 期望它们位于具有特定名称的特定位置。您可以通过使用 --input (我认为)添加它们来避免这种情况,而是使用结构化路径。示例见here

[更新]

我可以运行未编译的代码,文件在:

google 闭包库位于:public_html/js/libraries/goog

角度输入:public_html/js/libraries/angular.1.0.8.js

public_html/js/libraries/app.js

public_html/js/libraries/ngTrader/account.js

public_html/js/libraries/ngTrader/account/accountSrvc.js

public_html/test.html

<body ng-app="ngTrader">
    <script src="js/libraries/angular.1.0.8.js"></script>
    <script src="js/libraries/goog/base.js"></script>
    <script>
        goog.require("ngTrader");
    </script>
</body>

必须使用以下命令创建 deps.js:

python \
 "/path/to/closure-library/closure/bin/calcdeps.py" \
 --path /path/to/public_html/js/libraries \
 --input /path/to/public_html/js/libraries/app.js \
 --output_mode deps \
 --output_file /path/to/public_html/js/libraries/goog/deps.js

【讨论】:

  • 我能够运行 calcdeps.py 以生成更新的 deps.js 文件,但现在我收到一条错误消息 Uncaught Error: Namespace "ngTrader" already declared.。我检查了整个代码,我唯一拥有goog.provide('ngTrader'); 的地方是在我的 app.js 文件中。这是deps.js 文件的副本。如果我确实让它工作,我是否需要在每次添加新文件或修改另一个文件的依赖项时运行 calcdeps?
  • @Jarek 您的 deps.js 不会显示多个提供,否则它将多次出现。如果此错误出现在 base.js(某处的​​第 192 行)中,那么您的 html 文件中可能有一个 goog.provide 吗?它应该是您的 html 文件中的 goog.require,因为它会开始加载所有需要的库。每次创建新的 goog.provide 时都应该运行 calcdeps,但不需要 --input 只需将 --path 指向 js 文件的根目录即可。尝试从项目的根目录运行以下命令:grep -H -r "goog.provide(.ngTrader.)" . | cut -d: -f1
  • @Jarek 也许你可以将它作为一个新项目签入github,我会看看。
  • 今天晚些时候我将创建一个分支并将我的更改上传到它。
  • 经过更多调试,问题在于我的代码执行顺序,我覆盖了闭包库提供的对象的属性。基本上在 accountSrvc.js 中,我创建了 ngTrader.account.accountSrvc 函数,在 account.js 中,我在创建模块时覆盖了基础对象 ngTrader.account。因此,当我尝试执行ngTrader.account.Service(ngTrader.account.accountSrvc) 时,accountSrvc 未定义,因为我覆盖了前一行中的基础对象。我最终将服务注册从 account.js 移动到 accountSrvc.js 的底部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-17
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多