3

我正在使用 angular2 Beta。并且在使用@Inject 注释将我的一项服务DI 到另一项服务时出现错误,无法找出我错在哪里。一切似乎都符合 Angular2 文档

我正在使用基于云的数据服务 - CloudDB - 来满足我的应用程序的数据需求。CloudDB 为我提供了一个基于 javascript 的客户端库,我可以将其包含在我的 js 应用程序中,并用于在我的 cloudDB 数据库中执行 CRUD 操作或调用我存储在我的 CloudDB 帐户中的其他自定义 API,例如 UserAuth API(用于验证用户凭据的 API)。在使用 cloudDB js 客户端 lib API 之前,我需要通过调用 CloudDB js 对象的 getClient 方法来提供我的 cloudDB 帐户的 URL 和 authKey。

在我的 angualar2 应用程序中,我创建了一个可注入服务类 - CloudDBProvider - 它将存储我的 CloudDB 帐户 URL 和 authKey 并调用 CloudDB.getClient 为我的 CloudDB 帐户设置提供程序的 js 客户端对象。

import {Injectable} from 'angular2/angular2'; 
///<reference path="../typeDefs/CloudDB.d.ts" /> //typedef of CloudDB js library

@Injectable()
export class CloudDBProvider {
    private cloudDBClient: CloudDB.JSClient; 
    public get cloudDBClient(): CloudDB.JSClient {
        return this.cloudDBClient;
    }


    constructor() {
        this.cloudDBClient = new CloudDB.getClient(
            "https://myaccount.CloudDB.com/",
            "AcfdsfmyDdCMHeadfsdsdfHdsf68" // account authKey
        );
    }
}

现在,我想在这个 angular2 应用程序中创建一个 UserUtils 服务,我想将上面的类注入到该服务中以获取 cloudDBClient 对象。从您的教程中了解到,我编写了如下所示的 UserUtils 服务类

import {Injectable, Inject} from 'angular2/angular2';
import {CloudDBProvider} from './CloudDBProvider';

@Injectable()
export class UserUtils {
private _userDetails: Object = {};
private _cloudDBProvider: CloudDBProvider;
private _cloudDBClient: Microsoft.WindowsAzure.MobileServiceClient;;

constructor( @Inject(CloudDBProvider) cloudDBPrvdr: CloudDBProvider) {
    this._cloudDBProvider = cloudDBPrvdr;
    this._cloudDBClient = this._cloudDBProvider.cloudDBClient;  //the public getter property in the class CloudDBProvider
}

public authenicateUser(p_strUserName: string, p_strUserPassword: string) {
    var p: Promise<any> = new Promise(
        (resolve: (result: any) => void, reject: (err: any) => void) =>
            this._cloudDBClient.userlogin(p_strUserName, p_strUserPassword).done( //using API 'userlogin' of cloudDB to authenticate user against my cloudDB's users table.
                (loginResult) => {
                    alert("from Userutils - You are now logged in as: " + loginResult.user.basicProfile.firstName);
                    resolve(loginResult);
                },
                (loginErr: any) => {
                    alert("Error: " + loginErr.request.responseText);
                    reject(loginErr);
                }
            )
    );

    return p;
}

}

然后我尝试在我的 LoginPage 组件中使用 UserUtils,如下所示:

import {Component} from 'angular2/core';
import {WelcomePage} from  "../views/welcome/welcome";
import {UserUtils} from  "../services/UserUtils";


@Component({
    templateUrl: 'app/login/login.html',
    providers: [UserUtils]
})
export class LoginPage {
    private _userUtils: UserUtils;

    constructor( userUtils: UserUtils) {
        this._userUtils = userUtils;
     } 


    public loginButtonClicked(event, userName, password) { //called when Login Button is clicked by user
         //...
        //... to-do field value verification 
        //...

        this._userUtils.authenicateUser(userName, password).then(
          (result) => {
              //navigate to WelcomePage
          },
           (err) => { alert(err); }

      );

   }
} 

当我使用 UserUtils 时,组件 LoginPage 不起作用。浏览器控制台抛出错误 - 没有 CloudDBProvider 的提供者!(LoginPage -> UserUtils -> CloudDBProvider)

请注意,如果我将 'authencateUser' 方法从 UserUtils 直接移动到 CloudDBProvider,并在 LoginPage 组件中使用 CloudDBProvider 进行用户身份验证,那么一切正常,用户在登录后通过身份验证并导航到欢迎页面。此外,如果我从 UserUtils 的构造函数中删除 @Inject(CloudDBProvider) cloudDBPrvdr,则不会引发错误并且应用程序正常工作,显然我不能在 UserUtils 中使用 CloudDBProvider,但关键是应用程序不会抛出任何错误,这意味着 @Inject 有问题。

任何线索我哪里出错了?

4

2 回答 2

1

据我了解,您的错误是在导入中更改了Injectable导入

import {Component, Inject, Injectable} from 'angular2/core';

根据我的说法,当我们使用@injectable注释时,无需@inject在构造函数中使用,您只需将服务与public标识符一起放入,即可将该服务用于同一类的任何其他方法。

于 2016-01-06T04:39:07.907 回答
0

也许您可以在组件的CloudDBProvider提供者列表中添加提供者:

@Component({
  templateUrl: 'app/login/login.html',
  providers: [UserUtils, CloudDBProvider]
})
export class LoginPage {
  (...)
}

或者在函数的第二个参数内的应用程序级别bootstrap

bootstrap(MainComponent, [CloudDBProvider]);

这个答案可以给你一些额外的提示:Angular2 Beta dependency injection

希望它可以帮助你,蒂埃里

于 2016-01-06T07:02:44.260 回答