다른 구성 요소에서 업데이트할 때 서비스 변수 변경을 감지하려면 어떻게 해야 합니까?
서비스 변수에서 업데이트된 값을 가져오려고 합니다(isSidebarVisible
) 다른 구성 요소에 의해 계속 업데이트됩니다(header
클릭 이벤트 포함(toggleSidebar
).
사이드 바.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SidebarService {
isSidebarVisible: boolean;
sidebarVisibilityChange: Subject<boolean> = new Subject<boolean>();
constructor() {
this.isSidebarVisible = false;
}
toggleSidebarVisibilty() {
this.isSidebarVisible = !this.isSidebarVisible
this.sidebarVisibilityChange.next(this.isSidebarVisible);
}
}
사이드바.구성 요소.ts
export class SidebarComponent implements OnInit {
asideVisible: boolean;
_asideSubscription: any;
constructor(private sidebarService: SidebarService) {
this.asideVisible = sidebarService.isSidebarVisible
this._asideSubscription = sidebarService.sidebarVisibilityChange.subscribe((value) => {
this.asideVisible = value
})
}
ngOnInit() {
}
}
header.component.ts(서비스 변수가 업데이트되는 위치)
export class HeaderComponent implements OnInit {
isSidebarVisible: boolean;
_subscription: any;
constructor(private sidebarService: SidebarService) {
this._subscription = sidebarService.sidebarVisibilityChange.subscribe((value) => {
this.isSidebarVisible = value
})
}
toggleSidebar() {
this.sidebarService.toggleSidebarVisibilty()
}
ngOnInit() {
}
}
서비스 변수 값의 변화를 확인할 수 있습니다.header.component.html
언제{{ isSidebarVisible }}
그러나 인sidebar.component.html
항상 기본값을 인쇄하고 변경 내용을 듣지 않습니다.
이것을 고치는 것을 도와주세요.
구독을 서비스로 이동하면 두 구성 요소 모두 이 값에 액세스할 수 있습니다.값이 한 번만 필요하면 sidebar.component에서 했던 것처럼 직접 사용할 수 있습니다.이 값으로 업데이트해야 하는 경우 getter를 사용할 수 있습니다(예: header.component).
사이드 바.service.ts:
@Injectable()
export class SidebarService {
isSidebarVisible: boolean;
sidebarVisibilityChange: Subject<boolean> = new Subject<boolean>();
constructor() {
this.sidebarVisibilityChange.subscribe((value) => {
this.isSidebarVisible = value
});
}
toggleSidebarVisibility() {
this.sidebarVisibilityChange.next(!this.isSidebarVisible);
}
}
사이드바.구성 요소.ts
export class SidebarComponent {
asideVisible: boolean;
constructor(private sidebarService: SidebarService) {
this.asideVisible = sidebarService.isSidebarVisible;
}
}
header.component.ts
export class HeaderComponent {
constructor(private sidebarService: SidebarService) { }
get isSidebarVisible(): boolean {
return this.sidebarService.isSidebarVisible;
}
toggleSidebar() {
this.sidebarService.toggleSidebarVisibility()
}
}
또한 두 구성 요소 모두에서 제목을 구독하고 값을 얻을 수 있습니다.
this.sidebarService.sidebarVisibilityChange.subscribe(value => {...});
주제에 대해 자세히 알고 싶다면 여기를 보세요.
@이셔우드가 저를 트랙에 올려주었습니다, 감사합니다!이것이 나의 상황과 가장 닮은 질문과 대답이었습니다.
저의 경우 AngularFire의 변경 사항을 수신하는 앱 전체 사용자 서비스가 있습니다.Auth(authState) 및 유효한 사용자가 있는 경우 이름, 이메일, 색상 등 사용자의 정보(/appusers/${user.id })가 포함된 해당 사용자의 AngularFirestore 문서에 대한 수신기를 설정합니다.userService에서 필요한 모든 페이지는 수신기이므로 해당 데이터를 라이브로 가져옵니다( .subscribe().
문제는 더 많은 데이터베이스 작업을 수행하기 전에 사용자 문서 준비(로그인 및 사용자 문서 가져오기)에 의존하는 페이지가 있다는 것입니다.딥 링크를 통해 내부 페이지로 바로 이동할 때 페이지는 사용자 문서가 준비되기 전에 데이터베이스 작업을 수행하려고 시도하여 오류/충돌로 이어집니다.
위의 @isherwoods 지침에 따라 앱 페이지에서 사용자 데이터가 준비될 때까지 기다렸다가 추가 데이터베이스 작업을 수행하는 방법은 다음과 같습니다.
user.service.ts
export class UserService {
userDocumentReady: boolean = false; // initial value is "userdoc is not ready"
userDocObserver: Subject<boolean> = new Subject<boolean>(); // observing that bool
constructor(
public fireauth: AngularFireAuth,
public afs: AngularFirestore,
) {
// watch variable
this.userDocObserver.subscribe(value => this.userDocumentReady = value);
this.fireauth.authState
.subscribe(user => {
if (user) {
this.afs.doc(`/tooluser/${user.uid}`).snapshotChanges()
.subscribe(usr => {
if (usr.payload.data()) {
console.log(`got user object from database:`, usr.payload.data());
this.currentUser = usr.payload.data();
this.userDocObserver.next(true); // flip UserDocumentReady flag
my tools.page.ts
// this is a logged-in page of the app,
// accessible through deep link https://my.app.domain/mytools
export class UsersPage implements OnInit {
constructor(
public userService: UserService,
) { }
ngOnInit() {
if (this.userService.userDocumentReady) {
console.log(`users: userdoc already here, no need to wait`);
this.setupPageData();
return;
}
// wait for userdoc before setting up page
this.userService.userDocObserver.subscribe(docReady => {
if (docReady){
console.log(`mytools: user ready value ${docReady}. now setup page.`);
this.setupPageData(); // this function does the database stuff that depends on the user data to be ready first
}
});
}
이 "나에게 효과"가 있고 행동은 일관성이 있는 것처럼 보입니다.브라우저 표시줄에 URL을 입력하면 이러한 직접 탐색이 발생하므로 개발 시에도 매우 유용합니다.그것을 기억하기 위해 이것을 쓰는 것 - 그리고 그것이 다른 사람들에게 유용할 수 있는지 누가 압니까?
이것은 나의 두 번째 이온 앱이기 때문에 만약 내 구조/설정에 심각한 문제가 있다면, 나는 이 솔루션에 대한 코멘트에 매우 관심이 있습니다 :)
편집: 이미 존재하는 경우 새 사용자 문서를 기다리지 않도록 mytools.page.ts에 체크 인을 추가했습니다.
언급URL : https://stackoverflow.com/questions/43159090/how-can-i-detect-service-variable-change-when-updated-from-another-component
'programing' 카테고리의 다른 글
MariaDB 쿼리의 잘못된 LIMIT 및 OFFSET 구문 (0) | 2023.09.02 |
---|---|
레지스트리 값이 있는지 테스트 (0) | 2023.09.02 |
PHP 삽입 쿼리를 사용하여 MySQL 데이터베이스에 현재 타임스탬프를 삽입하는 방법 (0) | 2023.09.02 |
기존 가상 환경을 정상적으로 업그레이드할 수 있습니까? (0) | 2023.09.02 |
python MySQLdb를 사용하여 *.sql 파일 실행 (0) | 2023.09.02 |