Меня это довольно сбивает с толку. Возможно, у меня нет четкого представления о том, как работает подписка.
Доработанная версия Angular 2
Цель: скрыть / показать меню навигации на основе ролей. Подход: я использую Facebook для аутентификации пользователей. После аутентификации будут извлечены роли пользователей, которые будут использоваться для определения необходимости отображения меню администратора. Вызов observable.next выполняется со значением true, и подписка на компонент панели навигации подхватит флаг и изменит isAdmin на true. (IsAdmin изначально имеет значение false). Это позволит отображать меню администратора.
Проблема: подписчик правильно подбирает флаг 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);
}
}
Что-то не так? Или есть лучший подход к достижению цели? Любое предложение будет принято с благодарностью! Спасибо
ОБНОВЛЕНИЕ
Получив ответ от peeskillet, я удалил строку changeDetection из компонента, и она работает.
Однако, когда я продолжаю работать над кодом, я перемещаюсь
self._securityService.setAdminStatus(isAdmin);
в другую службу (в данном случае службу Facebook) и вызовите эту службу из компонента приложения. Подписка в 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();
}
}
Это довольно интересно. По-видимому, мне нужно узнать больше об обнаружении изменений angular 2. Если кто знает хорошую ссылку, поделитесь, пожалуйста, со мной.
Спасибо!!