如何在 Ember CLI 应用程序中访问 Ember 全局“App”变量?

Posted

技术标签:

【中文标题】如何在 Ember CLI 应用程序中访问 Ember 全局“App”变量?【英文标题】:How do I access the Ember global 'App' variable in an Ember CLI application? 【发布时间】:2014-11-10 21:30:14 【问题描述】:

我正在使用 Ember CLI 创建一个 Ember 应用程序。我有一个调用我创建的组件的视图。我正在尝试访问全局 App 变量来创建我的组件并将其插入到我的布局中。

错误: Uncaught ReferenceError: App is not defined

我该如何解决这个问题?

app.js

import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';

Ember.MODEL_FACTORY_INJECTIONS = true;

var App = Ember.Application.extend(
  modulePrefix: 'client-web', // TODO: loaded via config
  Resolver: Resolver
);

loadInitializers(App, 'client-web');

export default App;

item-table.js(这是一个视图)

import Ember from 'ember';

export default Ember.View.extend(
    templateName: 'item-table',

    didInsertElement: function() 
        // All my other code here

        App.FreestyleChartComponent.create().appendTo($('#wp-chart td')); // This throws an error.
    
);

app/components/freestyle-chart.js

import Ember from 'ember';

export default Ember.Component.extend(
    templateName: 'components/freestyle-chart',

    didInsertElement: function() 
        console.log('Inserted the component.');
    
);

【问题讨论】:

我已经删除了我的答案,因为它没有帮助。对不起,伙计。 【参考方案1】:

我可以想到两种方法。第一种是手动将App放到全局范围内。

var App = window.App = Ember.Application.extend();

第二个是将App导入到你的视图中:

import App from './path/to/app/file';

后者仅在 Ember CLI 支持循环引用时才有可能。官方 ES6 规范支持它们,但许多转译器不支持(我的不支持)。

但是,我认为这不是您的根本问题。大多数情况下,您不应该在 Ember CLI 中访问全局变量。与其将FreestyleChartComponent 放在App 命名空间中,不如将它放在一个模块中并像其他任何模块一样导入它?全局变量是不可避免的(我今天经历过),但你应该尽量减少它们。

【讨论】:

我试过第一个选项,没用。第二个编译但现在错误是“未捕获的类型错误:无法读取未定义的属性'创建'”。如何创建模块?找不到太多这方面的信息。抱歉新手问题。此外,假设我什至没有在这里问问题,您将如何在 Ember CLI 应用程序中动态创建组件?我当前的脚本是否正确? 如果第一个选项不起作用,那么您做错了其他事情。一个特定的错误可以帮助我们追踪该问题。至于第二个不起作用,听起来App.FreestyleChartComponent 不存在。如果没有更多代码,我真的无法帮助您诊断。 我基本上是在关注:emberjs.jsbin.com/axUNIJE/1/edit。除了我的应用是使用 Ember CLI 创建的这一事实之外,没有任何不同。 你能告诉我们你声明FreestyleChartComponent的代码吗?【参考方案2】:

我同意您不应该通过全局命名空间访问您的应用程序,但是 ember-cli 实际上确实使您的应用程序成为全局应用程序,您的应用程序名称是变量的名称。

如果您在ember-cli 项目中打开/app/index.html,您应该会在底部看到一个script 标签,看起来像...

<script>
  window.YourAppName = require('your-app-name/app')['default'].create(YourAppNameENV.APP);
</script>

在上面的示例中,YourAppName 将是您的应用程序作为全局可用

【讨论】:

【参考方案3】:

导入你想要的组件:

import FreestyleChartComponent from 'app_name/app/components/freestyle-chart';

【讨论】:

我试过了,现在可以找到组件了。谢谢!但是,错误现在显示“断言失败:您不能附加到现有的 Ember.View。请考虑改用 Ember.ContainerView”。我刚刚将视图更改为 ContainerView,它现在显示“未捕获的错误:断言失败:您尝试附加到 ([object Object]) 但它不在 DOM 中”。视图的模板也不在页面上。 您应该在另一个问题中提出这个问题,而不是在此处的评论中。这与原始问题无关。【参考方案4】:

没有直接的方法可以做到这一点,因为 Ember CLI 希望您使用公共 API 及其给定组件,而不是直接访问 App 实例。

大多数解决方案包括使 App 实例全局化,而这个没有。我没有对此进行测试,但我认为这应该可行:

appname/utils/application.js

export default 
   instance: null
;

appname/instance-initializers/application.js

import application from 'appname/utils/application';

export default 
  name: 'app-initializer',
  initialize: function (application) 
     application.instance = application;
  
;

现在

import application from 'appname/utils/application';

并在需要应用程序实例的任何文件中使用application.instance

【讨论】:

【参考方案5】:

刚刚使用 Ember 3.7 进行了测试。

import App from 'app-name/app';

app-name 必须替换为您的应用程序的名称(我猜是 package.json 中的那个)。

【讨论】:

以上是关于如何在 Ember CLI 应用程序中访问 Ember 全局“App”变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ember-cli 插件组件中找到 npm 模块

如何调试在 phantomjs 中运行的 ember-cli 测试

您如何在开发中从 https://localhost:4200 提供 ember-cli

如何在 ember cli 生成的模型中设置休息适配器

如何在 ember-cli 中导入 amd 模块?

如何使用 Ember CLI 进行生产就绪构建?