如何在@Component声明中使用服务或全局函数?

时间:2016-11-08 20:49:18

标签: angularjs angular typescript angular-routing angular-services

我有一项服务可以解决与我的环境相关的一些路由问题,现在我需要处理模板路由问题

理想情况下,我可以做到这样的事情:

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

当然,这不起作用,因为服务没有在组件声明中使用,所以我得到运行时控制台错误:

  

requests:38错误:TypeError:无法读取属性' pathSvc'的   未定义的(...)

genaral中的Typescript和模块化JS对我来说是一件新事物。也许有更直接的方法将我的函数导入到一堆模块中并在任何我想要的地方使用它?

我意识到这不是一种最佳方法,我应该使用

获得这些结果
<base href="/{alias}" />

方法论,但现在没有发生。

缺点是,当我试图使我的ASP.Net MVC + Angular 2应用程序更动态地了解其托管环境并处理后端和前端路由冲突时,所有这些都停止了工作。我想以更正确的方式使用这种方式&#34;但目前,我只是需要它来工作,所以我的老板很高兴,全局路由脚本似乎就是这样。

2 个答案:

答案 0 :(得分:1)

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

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

例如,如果您想要一个为您构建URL的帮助程序,您可以创建一个类并在组件声明中使用它,只需导入它即可。

//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一起使用(无论出于何种原因,需要角度代表..),你可以使用静态方法制作一个可注射类。

//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文件中。

答案 1 :(得分:1)

我已经解决了这个问题,我通过在我的配置/ appSettings中设置baseHref来解决它。使Angular页面容器成为.ASPX页面,在页面加载时,从配置中设置baseHref。以下是我的Web.config中的代码段:

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

以下是重写规则,以使您的Angular应用程序在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>