角度2订阅值更改未反映在html上

Chu*_*uck 6 subscribe observable role-based-access-control angular2-changedetection angular

这让我很困惑。我可能对订阅的工作方式没有深刻的了解。

Angular 2最终版本

目标:根据角色隐藏/显示导航菜单方法:我使用Facebook来验证用户身份。身份验证后,将检索用户角色,并将其用于确定是否应显示“管理”菜单。使用true进行observable.next调用,导航栏组件订阅将拾取该标志并将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));
 }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

安全服务

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

constructor(){}

setAdminStatus(flag){
    this.isAdmin.next(flag);
    }
}
Run Code Online (Sandbox Code Playgroud)

这有什么问题吗?还是有更好的方法来实现目标?任何建议将不胜感激!谢谢

更新

有了peeskillet提供的答案,我从组件中删除了changeDetection行,它可以正常工作。

但是,当我进一步处理代码时,我会移动

self._securityService.setAdminStatus(isAdmin);
Run Code Online (Sandbox Code Playgroud)

到另一个服务(在这种情况下为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));
    }
}
Run Code Online (Sandbox Code Playgroud)

更新的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是相当有趣的。显然,我需要了解有关角度2变化检测的更多信息。如果有人知道一个很好的参考,请与我分享。

谢谢!!

Pau*_*tha 5

这是因为您正在使用changeDetection: ChangeDetectionStrategy.OnPush。这意味着仅在@Input更改s个输入1时才发生组件的更改检测。

因此,如果删除@Component.changeDetection,它应该可以工作。

如果您的目标是保留OnPush策略,则一种选择是使用ChangeDetectorRef

class SomeComponent {
  message;

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

  ngOnInit() {
    this.service.subscribe(data => {
      this.message = data;
      this.cdr.detectChanges();
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

1-另请参见Angular 2中的ChangeDetectionStrategy.OnPush和Observable.subscribe