【问题标题】:get set variable in typescript在打字稿中设置变量
【发布时间】:2017-03-11 03:01:09
【问题描述】:

我正在使用带有打字稿的 angular2。在其中一项服务中,我正在设置并获取如下变量的值:

import {Injectable} from '@angular/core';

@Injectable()
export class UserProfileService {
    isLoggedIn: boolean;

    constructor() {

    }

    setLoggedInStatus(status) {
        console.log('status: ', status);
        this.isLoggedIn = status;
        console.log('this.isLoggedIn : ', this.isLoggedIn)    //setting to true or false here
    }

    getLoggedInStatus() {
        return this.isLoggedIn;
    }
}

但是当我尝试使用 getLoggedInStatus() 获取值时,我每次都不确定。 为什么会这样?

在这里设置

import {Component} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {SharedService} from '../../shared.service';
import {UserProfileService} from '../../authComponent/login/user-profile.service';

@Component({
    selector: 'login',
    templateUrl: 'app/components/authComponent/login/login.component.html',
    providers: [SharedService, UserProfileService]
})

export class LoginComponent implements OnInit {
    matched: boolean = false;

    constructor(private sharedService: SharedService, private userService: UserProfileService) {
    }

    ngOnInit() {
        this.myForm = new FormGroup({
            email: new FormControl('', [Validators.required]),
            password: new FormControl('', [Validators.required])
        })
    }

    submit({value, valid}) {
        if (!valid) {
            return;
        }
        else {
            this.sharedService.getData('users')
                .subscribe(result => {
                    console.log('result: ', result, 'value passed: ', value)
                    result.forEach((record) => {
                        if ((record.email == value.email && record.password == value.password) && !this.matched) {
                            this.matched = true;
                        }
                        else {
                            this.matched = false;
                        }
                    });

                    if (!this.matched)
                        console.log('wrong credentials entered');
                    this.userService.setLoggedInStatus(this.matched);
                })

        }
    }
}

到达这里

import {Injectable} from '@angular/core';
import {
    CanActivate,
    CanActivateChild,
    Route,
    Router,
    ActivatedRouteSnapshot,
    RouterStateSnapshot
} from '@angular/router';

import {UserProfileService} from './authComponent/login/user-profile.service';

@Injectable()
export class CanActivateAuthGuard implements CanActivate, CanActivateChild {
    constructor(private userProfileService: UserProfileService, private router: Router) {
    }

    canActivateChild(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        return this.canActivate(next, state);
    }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        console.log('this.userProfileService.getLoggedInStatus: ', this.userProfileService.getLoggedInStatus())
        if (this.userProfileService.getLoggedInStatus()) {
            return true;
        }
        this.router.navigate(['/login'], {queryParams: {redirectTo: state.url}});
        return false;
    }
}

【问题讨论】:

  • 您在一个组件中使用setLoggedInStatus,在另一个组件中使用getLoggedInStatus,对吗?
  • 你是如何设置和获得的?
  • 您可能在服务的另一个实例上调用它。如果您不发布重现问题的示例,就无法说出原因。
  • @camaron:在不同的组件中是的
  • @BhushanGoel 好的,你的问题是 JB Nizet 指出的。您必须确保UserProfileService 仅由一个 NgModule 提供,没有其他地方提供。

标签: angular typescript


【解决方案1】:

Angular 中的服务是可注入的,即在需要时调用它们。 如果您正在使用配置变量和全局变量,您可以通过在 AppModule 中声明来使用它们,如下所示

    import {Component, NgModule} from '@angular/core'
    import {BrowserModule} from '@angular/platform-browser'

    @Component({
      selector: 'my-app',
      template: `
        <div>
          <h2>{{name}} Sample</h2>
          {{myConfiguration | json}}
        </div>
      `,
    })
    export class App {
      name:string;
      myConfiguration:any=myConfiguration;
      constructor() {
        console.log(myConfiguration);
        this.name = 'Global Configuration'
      }
    }

    @NgModule({ 
      imports: [ BrowserModule ],
      declarations: [ App ],
      bootstrap: [ App]
    })
    export class AppModule {
        var myConfiguration={id:1,devmode:true};  

    }

LIVE DEMO

【讨论】:

    【解决方案2】:

    在调用 `setLoggedInStatus(..) 之前,您是否调用过 getLoggedInStatus()

    如果是这样,您从未初始化您的 isLoggedIn 布尔成员变量,因此,它仍然是未定义的。

    你可以通过在声明时初始化isLoggedIn来绕过这个问题

    export class UserProfileService {
       isLoggedIn = false;  // or true
    .....
    

    请注意,我不必声明类型 - Typescript 从它初始化的值推断它。

    编辑:

    通过您更新的帖子,我注意到您将服务添加到组件的提供者列表中。根据您希望如何使用该服务,您不想这样做。将服务添加到组件的提供者列表中或多或少对 Angular 表示我不希望该组件与其他任何人共享我的服务实例——我希望该组件拥有自己的该服务实例。

    根据您的使用情况,您实际上希望将该服务添加到您的 AppModule 的提供者列表中。

    see this other question for almost the same scenario

    【讨论】:

      【解决方案3】:

      要拥有一个单例服务实例,只需将该服务作为提供者添加到一个模块中,不要在其他地方提供该服务。

      最简单的方法是将服务添加到app.modules.ts providers。

      app.module.ts:

      @NgModule({ 
        ...
        providers:[
           UserProfileService
        ]
      })
      export class AppModule {}
      

      这样就可以了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 2021-11-29
        • 2021-06-11
        • 1970-01-01
        相关资源
        最近更新 更多