3

이것은 매우 혼란 스럽습니다. 구독 방법에 대한 확실한 이해가 없을 수도 있습니다.각도 2의 구독 값 변경이 html에 반영되지 않습니다.

각도이 최종 버전

목표 : 숨기기/표시 탐색 메뉴 역할을 접근 방식을 기반으로 : 나는 사용자를 인증하기 위해 페이스 북을 사용합니다. 인증 후에는 사용자 역할을 검색하여 관리자 메뉴를 표시할지 결정하는 데 사용됩니다. observable.next 호출은 true로 설정되고 nav bar compenent subscription은 플래그를 선택하고 isAdmin을 true로 변경합니다 (isAdmin은 false로 시작 함). 그러면 Admin 메뉴가 표시됩니다.

문제점 : true 플래그가 구독자에 의해 올바르게 선택되고 isAdmin이 true로 설정됩니다. 그러나 관리자 메뉴가 표시되지 않습니다.

navbar.component.ts

@Component({ 
selector: 'as-navbar', 
templateUrl: 'app/shared/navbar/navbar.html', 
changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class NavbarComponent { 
@Input() brand: string; 
public isAdmin:boolean; 

constructor(private _securityService:SecurityService){ 
    let self = this; 

    this._securityService.isAdminObservable.subscribe(function (flag) { 
     this.isAdmin = flag; 
     console.log('subscribe received on navbar'); 
    }.bind(this)); 
} 
} 

navbar.html

 <li class="dropdown" *ngIf="isAdmin"> 
     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Admin<span class="caret"></span></a> 
     <ul class="dropdown-menu"> 
     <li><a [routerLink]="['/campaigns']">Campaigns</a></li> 
     <li><a [routerLink]="['/products']">Products</a></li> 
     <li><a [routerLink]="['/products']">Reports</a></li> 
     </ul> 
    </li> 

app.component.ts

constructor(private _http: Http, private _jsonp: Jsonp, private _securityService:SecurityService) { 
    this.appBrand = CONSTANTS.MAIN.APP.BRAND; 

    let self = this; 
    setInterval(function(){ 
     self._securityService.setAdminStatus(true); 
     console.log('set from app component'); 
    }, 5000) 
} 

security.service.ts

@Injectable() 
export class SecurityService{ 
public isAdmin:Subject<boolean>=new Subject<boolean>(); 
public isAdminObservable = this.isAdmin.asObservable(); 

constructor(){} 

setAdminStatus(flag){ 
    this.isAdmin.next(flag); 
    } 
} 

문제가 있습니까? 아니면 목표를 달성하기위한 더 나은 접근법이 있습니까? 모든 의견을 크게 높이세요! 감사

UPDATE peeskillet에서 제공하는 대답

, 나는 구성 요소에서 changeDetection 라인을 제거하고 그것을 작동합니다. 내가 더 코드를 작업 할 때

그러나, 나는 다른 서비스에 (이 경우 페이스 북 서비스)
self._securityService.setAdminStatus(isAdmin); 

를 이동하고 응용 프로그램 구성 요소에서 해당 서비스를 호출합니다. navbar.compoenent.ts에 가입하면 변경 사항이 적용되지만 변경 감지는 실행되지 않습니다. 수동으로 감지 기능을 작동시켜야 제대로 작동합니다.

업데이트 navbar.component.ts

@Component({ 
selector: 'as-navbar', 
templateUrl: 'app/shared/navbar/navbar.html' 
}) 
export class NavbarComponent { 
@Input() brand: string; 
public isAdmin:boolean=false; 

constructor(private _securityService:SecurityService, private cdr: ChangeDetectorRef){ 
    this._securityService.isAdminObservable.subscribe(function (flag) { 
      this.isAdmin = flag; 
      this.cdr.detectChanges(); 
      console.log('subscribe received on navbar'); 
     }.bind(this)); 
    } 
} 

업데이트 app.component.ts

@Component({ 
    selector: 'as-main-app', 
    templateUrl: 'app/app.html' 
}) 
export class AppComponent { 
    public appBrand: string; 
    constructor(private _http: Http, 
      private _facebookService:FacebookService 
) { 
     this.appBrand = CONSTANTS.MAIN.APP.BRAND; 
     this._facebookService.GetLoginStatus(); 
    } 
} 

이 상당히 흥미 롭다. 분명히, 각도 2 변경 감지에 대해 더 자세히 알아야합니다. 누구든지 훌륭한 참고 자료를 알고 있다면 나와 공유하십시오.

감사합니다.

답변

1

changeDetection: ChangeDetectionStrategy.OnPush을 사용하고 있기 때문입니다. 즉, @Input 입력을 변경할 때만 구성 요소의 변경 감지가 발생합니다. .

따라서 @Component.changeDetection을 제거하면 올바르게 작동합니다. 또한 ChangeDetectionStrategy.OnPush and Observable.subscribe in Angular 2를 참조 - OnPush 전략을 유지에 목표 인 경우

, 다음 하나의 옵션은 ChangeDetectorRef

class SomeComponent { 
    message; 

    constructor(private service: Service, private cdr: ChangeDetectorRef) { 
    } 

    ngOnInit() { 
    this.service.subscribe(data => { 
     this.message = data; 
     this.cdr.detectChanges(); 
    }) 
    } 
} 

1 사용, 명시 적으로 변경 감지를 강제하는 것

+0

이것은 대단합니다! 답변 해주셔서 감사합니다. changeDetection을 제거했습니다 : ChangeDetectionStrategy.OnPush와 코드가 작동합니다! 흥미로운 것은 있습니다. 논리를 다른 서비스로 옮겼습니다. (Facebook 서비스) Facebook에서 사용자 정보를 반환하면 데이터베이스에서 역할을 선택하고 next() 플래그를 사용합니다. 구독으로 선택했지만 변경 사항이 감지되지 않았습니다. 나는 여전히 작동하도록 changeDetection을 수동으로 트리거해야한다. 이유가 궁금합니다. 코드를 업데이트했습니다. – Chuck

+0

예, 확실하지 않습니다. –

+0

게시물 하단의 댓글과 관련하여 [다음은 훌륭한 참고 자료입니다] (http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html) –