通过index.ts文件

时间:2016-05-17 10:59:55

标签: typescript angular

我知道这个例外:

  

意外的指令值' 未定义'在组件的视图' AppComponent '

很常见,但没有其他问题对我有帮助,因为它们经常引用循环依赖或缺少export语句。但没有解决方案适合这个问题...

我有一个具有以下结构的项目

src/
    myproject/
        components/
        services/
        templates/
        ...
        main.ts
    index.html
    systemjs.config.js
public/
    libs/                   <- required libs, copied from node_modules
    myproject/              <- compiled .ts files and copied resources from /src/myproject
    index.html              <- copied from /src/myproject
    systemjs.config.js      <- copied from /src/myproject
gulpfile.ts
*.json                      <- tsconfig, package, typings, ...

部署项目的过程如下:编译.ts个文件,将它们输出到/public。将所有资源(.ts个文件除外)复制到/public。将所有必需的库复制到/public/libs

我使用的是打字稿1.9,因为我在paths中使用tsconfig.json选项。该文件包含以下路径映射:

// excerpt from /tsconfig.json
{
    "compilerOptions": {
        // more options
        "paths": {
            "myproject/*": ["./src/myproject/*"]
        }
        // more options
    }
}

我的所有Angular2组件都在/src/myproject/components文件夹中,并且有一个index.ts文件可以导出每个已定义的类。该文件如下所示:

// /src/myproject/components/index.ts
export * from './app.component';
export * from './a.component';
export * from './b.component';
export * from './c.component';

这种设置的原因是能够具有良好的外观和简单的导入。例如,如果我需要ComponentAComponentBComponentC(在/src/myproject/components/{a,b,c}.component.ts中定义),那么我可以发表以下声明:

// excerpt from /src/myproject/components/app.component.ts
import  { ComponentA, ComponentB, ComponentC } from 'myproject/components';

这确实很有效:编译时没有问题,在浏览器中访问它时没有问题(systemjs.config.js负责正确的解决方案)

但有一个例外。如果我在AppComponent文件(/src/myproject/components/app.component.ts)中导入主main.ts/src/myproject/main.ts),请执行以下操作:

// excerpt from /src/myproject/main.ts
import { AppComponent } from 'myproject/components';

尝试在浏览器中查看myproject时出现以下异常:

  

EXCEPTION :意外的指令值&#39; 未定义&#39;在组件的视图&#39; AppComponent &#39;

但是,如果我将此导入更改为以下内容:

// excerpt from /src/myproject/main.ts
import { AppComponent } from 'myproject/components/app.component';

一切都按预期工作。请注意,main.ts是此导入无效的唯一文件。所有其他进口都像魅力一样。例如,在AppComponent中,就像您在上面看到的一样。

如果我要写下所有内容,这个问题就会变得很大,所以请原谅我决定只添加一个MWE作为GitHub存储库。您可以从以下网址获取完整的代码:

https://github.com/christiandreher/ang-exc-mwe

我也推了/public目录。使用浏览器访问它,您在技术上应该得到相同的错误。如果您想自己构建,可以使用gulp cleantsc(注意:gulp build由于gulp-typescript中的错误而无法正常工作),gulp resourcesgulp libs

所以问题是:为什么每个导入都有效,除了main.ts中的第一个?我真的很喜欢这个设置,因为我可以非常方便地导入所有内容而且看起来很简单好。 此外,我一直希望

我真的很感激任何帮助,因为这是一个很大的问题,说实话,不那么最小的工作示例...

更新:到目前为止,我只收到了有关如何修复异常的答案,但我已在OP中自行提供了此修复程序。我知道如何避免它,但我不想使用相对导入,我希望它在任何地方都是一致的。那么我该怎么做来解决这个例外呢?这是什么原因?如果它不可修复:为什么?我必须解决这个问题? TypeScript,Angular,......?

更新2 :由于我还没有设法让它发挥作用,我现在将开始赏金

3 个答案:

答案 0 :(得分:2)

export * from './app.component';放在index.ts

的末尾
// /src/myproject/components/index.ts
export * from './a.component';
export * from './b.component';
export * from './c.component';
export * from './app.component';

我认为它应该有用,因为我遇到了同样的问题。

如果没有,请执行以下操作:

  • index.ts视为已将所有导出文件的代码写入其中。

  • 然后根据稍后定义首次使用规则

  • 重新排序导出
  • 不要使用index.ts作为其中导出的文件的代理,并使用也从同一index.ts文件导出的其他文件,而不是反之亦然(又名:循环依赖)。换句话说

  • 无论您在./some-component进行导入,都不要在index.ts使用some-other-component,如果index.ts (read Directory)位于同一index.ts,则必须使用servicesindex.ts导入彼此,这将失败。

  • 同样适用于typeswitch

  • 它现在应该工作了,如果没有,请查看AppComponent的构造函数,看看是否有其他for $node in /descendant::*/(., @*) let $value := ( typeswitch ($node) case element() return $node/text() case attribute() return data($node) default return () ) where $value return <R> <P>{ string-join(($node/name(), $node/ancestor::*/name()), "/") }</P> <V>{ $value }</V> </R> 导出正在使用,彼此有内部依赖关系,然后重新排序同样的规则。

  • 这就是为什么我们不在一个文件中定义两个类的原因。

答案 1 :(得分:0)

我会像这样导入:

// excerpt from /src/myproject/main.ts
import { AppComponent } from './components';

使用以下SystemJS配置:

System.config({
  (...)
  packages: {
    (...)
    src: {
      main: 'index.js',
      defaultExtension: 'js'
    }
  }
});

答案 2 :(得分:0)

更新

对我来说,只有相对路径才能与我合作,当我导入绝对路径不能正常工作时,除了node_modules中的那些我发现一个有用的链接可以帮助你Angular2 & TypeScript importing of node_modules

您需要将导入更改为

import { AppComponent } from './components';

它适用于我