簡體   English   中英

Angular 2可觀察訂閱不會觸發

[英]Angular 2 observable subscription not triggering

我有一個訂閱可觀察不觸發的問題。

我有一個使用側面導航布局指令的布局,如下所示:

<md-sidenav-layout class="nav-bar">


    <md-sidenav #start>
        <nav>
            <a [routerLink]="['/home']">Home</a>
        </nav> 
        <button md-button (click)="start.close()">Close</button>
    </md-sidenav>

    <router-outlet></router-outlet>

</md-sidenav-layout>

我需要做的是從路由器插座顯示的組件打開側面導航。

一個這樣的組件可能如下所示:

@Component({

    providers: [SidenavService, MdIconRegistry],
    directives: [MdIcon],
    templateUrl: `<md-icon (click)="toggleSidenav()">menu</md-icon>`,
    styleUrls: ["./home.component.scss"]
})

export class Home {

    myColor: string;

    constructor(private sidenavService: SidenavService) {
        this.myColor = "primary";

        this.sidenavService.getSidenavObs().subscribe(state => {console.log("state change")});
    }


    toggleSidenav() {

        this.sidenavService.toggleSidenav("open");
    }

}

我創建了一個返回如下observable的服務:

@Injectable()
export class SidenavService {

    private toggle = new Subject<string>();
    private toggleObs = this.toggle.asObservable();

    getSidenavObs() {
        return this.toggleObs;
    }

    toggleSidenav(state: string) {
        this.toggle.next(state);
    }

}

最后是父類的代碼(屬於側面導航布局HTML):

@Component({
  providers: [MdSidenav, SidenavService],
  directives: [ROUTER_DIRECTIVES, MD_SIDENAV_DIRECTIVES, MD_BUTTON_DIRECTIVES],
  selector: "app",
  templateUrl: "app.html",
  styleUrls: ["./app.scss"],
})

export class App {

  subscription: Subscription;

  constructor(private sidenavService: SidenavService, private sidenav: MdSidenav) {
    this.subscription = sidenavService.getSidenavObs().subscribe( status => {
      console.log("state change");
      sidenav.open();
    }, error => {
      console.log(error);
    }, () => {
      console.log("completed");
    });
  }
}

現在我的問題是App組件中的訂閱不會觸發,但Home組件中的訂閱(路由器插座顯示的內容)會按預期觸發。

我在這里錯過了什么嗎?

我遵循了這個指南: https//angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

您的App和Home組件之間未共享相同的服務實例,因為您已將SidenavService列為SidenavService的提供者。

當您在組件裝飾器的providers條目中定義服務提供者時,該服務隨后可用於該組件及其所有子組件作為單例,這意味着將使用該服務的相同實例。

如果重新定義子組件中的提供程序,它將創建該服務的實例,並且將不再與其父/祖先共享相同的服務實例。

如果您在App和Home組件中使用SidenavService並且需要相同的實例,則應僅在App組件中提供它並將其從Home的providers條目中刪除。

有關DI的更多信息,請閱讀以下鏈接: https//angular.io/docs/ts/latest/guide/dependency-injection.html https://angular.io/docs/ts/latest/guide /hierarchical-dependency-injection.html

問題在於,與其他框架相反,Angular似乎並沒有強制Service s默認為單例

因此,當您聲明自己的每個Component都擁有自己的Service實例時,您會遇到這種情況。 這導致每個實例具有不同的屬性( toggletoggleObs )。 示意圖:

App - > SidenavService [ 實例A ]

首頁 - > SidenavService [ 實例B ]

您需要更改聲明以匹配單一服務 ,如Angular文檔中所述 這導致在所有Components僅共享Service的單個實例。 示意圖:

App - > SidenavService [ 實例A ]

首頁 - > SidenavService [ 實例A ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM