1

我有一个服务,它具有与我的环境有一定的路由问题帮助,现在我需要应付模板路由问题如何在@Component声明中使用服务或全局函数?

理想我想能够做这样的事情:

import { PathSvc } from './globals/path.svc'; 
@Component({ 
    templateUrl: this.pathSvc.alias + '/app/my.comp.html' 
}) 
export class MyComp { 
    constructor(private pathSvc: PathSvc) { }   
} 

当然不工作,因为服务不发在组件声明中使用,所以我得到一个运行控制台错误:

requests:38 Error: TypeError: Cannot read property 'pathSvc' of undefined(…)

打字稿和模块化的JS在genaral是一个新的东西给我。也许有更直接的方式将我的函数导入一堆模块并在任何我想要的地方使用它?

我意识到这是不是最佳做法,我应该使用

<base href="/{alias}" /> 

方法来获取这些结果,但是不是现在发生的事情。

总而言之,当我尝试让我的ASP.Net MVC + Angular 2应用程序更加动态地意识到其宿主环境并处理后端和前端路由冲突时,所有这些都停止了工作。我希望以更正确的方式来实现这一目标,但目前我只需要它的工作,所以我的老板很高兴,并且全球路由脚本似乎是这样。

+0

DI在装修中使用。有可能是黑客,但我很确定他们不能用AoT做例子。 –

+0

是的,我认为它不应该这样工作,但不能以某种方式从另一个文件中导入一个函数,我可以在@Component声明中使用它?我只是不喜欢我现在正在做的是在10个不同的组件中复制代码,所以我可以注入正确的路径前缀。 – Methodician

回答

1

如果我正确理解,你想创建一个服务,可以作为角的DI过程中的帮手。

就像@Günter_Zöchbauer说的,Injectable不能用在Ng2对象(Component,Injectable ...)实例的外部,但在你的情况下,创建一个注射是无关紧要的。 创建角度应用并不意味着所有的文件必须包含的角度对象,你还可以创建基本的类/常数..

例如,如果希望建立一个网址给你的帮手,可以创建一个类,并通过简单地导入它来在组件声明中使用它。

//urlbuilder.ts 
const host:string = 'http://foo.bar.com'; 
export class UrlBuilder { 
    static generate(file:string = '') { 
     return host + file; 
    } 
} 

// component.ts 
import {UrlBuilder} from './urlbuilder'; 

@Component({ 
    templateUrl: UrlBuilder.generate('/foo.html') 
}) 
export class FooComponent {} 

你甚至可以导出一个函数而不是类,它也可以工作。 以下代码显示与上面相同的代码,但带有一个功能和一个es6标签。

//urlbuilder.ts 
const host:string = 'http://foo.bar.com'; 
export const UrlBuilder = urlBuilderFn; 

//basic tag function that build a template string with potential variables 
function urlBuilderFn(strs, ...raws) { 
    let builtStr = '', length = strs.length; 

    for(let i = 0; i < length; i++) 
     builtStr = strs[i] + (raws[i] !== undefined && raws[i] !== null ? raws[i] : ''); 

    return host + builtStr; 
} 


// component.ts 
import {UrlBuilder as url} from './urlbuilder'; 

@Component({ 
    templateUrl: url`/foo.html` 
}) 
export class FooComponent {} 

但是,如果想使用你的助手与DI太(不管是什么原因,需要角度DEPS ..)可以使注射剂类的静态方法。

//urlbuilder.ts 
const host:string = 'http://foo.bar.com'; 

@Injectable() 
export class UrlBuilder { 

    constructor(private http:Http) {} 

    static generate(file:string = '') { 
     return host + file; 
    } 

    doSomething() { 
     return this.http.get(UrlBuilder.generate('/foo/bar')) 
    } 
} 

// component.ts 
import {UrlBuilder} from './urlbuilder'; 

@Component({ 
    templateUrl: UrlBuilder.generate('/foo.html') 
}) 
export class FooComponent { 

    constructor(private builder:UrlBuilder) {} 

    ngOnInit() { 
     this.builder.doSomething() 
    } 

} 

在另一方面,如果你唯一的问题是与模板你为什么不直接写他们作为模板字符串或只是与你的任务管理器中导入它们(的WebPack ..)。一般来说,如果您没有动态视图,那么必须从服务器生成它们,而不是使用http调用来检索它们,并直接将它们加载到JavaScript文件中。

+0

谢谢你的深入解释。我没有测试过它,但是这看起来像是真正彻底地回答了我的查询的内容,并且您给了我很多尝试的方法以及我可以在其他场景中使用的工具和知识。另外,尽管我喜欢使用html文件的所有intellisense,zen编码和自动填充来编写我的模板的过程,但只需将它放在字符串中进行生产就行了。 – Methodician

1

我已经处理了这个问题,并通过在我的配置/ appSettings中设置baseHref来解决这个问题。使Angular页面容器成为.ASPX页面,在页面加载时,从配置中设置baseHref。以下是我的网页中的摘录。配置:

<appSettings> 
    <add key="AppBaseUrl" value="/MyAngularApp/" /> 
</appSettings> 

这里是重写规则,使您的角度应用功能正常,而在IIS所驻留:是不应该

<rewrite> 
    <rules> 
    <rule name="Rewrite Index to Root" stopProcessing="true" enabled="true"> 
     <match url=".*" /> 
     <conditions> 
      <add input="{URL}" pattern="^(.*)(/index.aspx)$" /> 
     </conditions> 
     <action type="Redirect" url="{C:1}" /> 
    </rule> 
    <rule name="Angular" stopProcessing="true" enabled="true"> 
     <match url="^(.*)$" ignoreCase="false" /> 
     <conditions logicalGrouping="MatchAll"> 
     <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> 
     <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> 
     </conditions> 
     <action type="Rewrite" url="index.aspx/{R:0}" appendQueryString="true" /> 
    </rule> 
    </rules> 
</rewrite> 
+0

有趣的方法,可能会做的伎俩,但我使用更现代的设置与剃刀和东西(没有aspx),所以我将不得不尝试找出如何翻译这一点。虽然我不太擅长web.config – Methodician

相关问题