Javascript Angular2从应用程序外部调用暴露的方法并丢失更改绑定

Javascript Angular2从应用程序外部调用暴露的方法并丢失更改绑定,javascript,angular,typescript,observable,angular2-changedetection,Javascript,Angular,Typescript,Observable,Angular2 Changedetection,我有一个公开给window的公共方法。此方法与组件对话,并修改我在模板中查看的变量。但是当我更改该值时,*ngIf()不会被触发 应用程序组件 constructor(private _public: PublicService,) { window.angular = {methods: this._public}; } 公共服务 export class PublicService { constructor( private _view

我有一个公开给
window
的公共方法。此方法与
组件
对话,并修改我在模板中查看的变量。但是当我更改该值时,
*ngIf()
不会被触发

应用程序组件

constructor(private _public: PublicService,) {
        window.angular = {methods: this._public};
    }
公共服务

export class PublicService {

    constructor(
        private  _viewManager: ViewManagerComponent,
    ) {}

    CallMe(){
        this._viewManager.renderView('page1')
    }
}
布局管理器组件

@Component({
    selector: 'view-manager',
    template: `<page *ngIf="view == 'page1'"></page>`
})
export class ViewManagerComponent {
    //This is the variable being watched
    view = "page";

    renderView = function(type){
        console.log(type)
        this.view = type;
        console.log(this.view)
    };
}

在这种情况下,Angular2不知道它需要运行更改检测,因为更改是由运行在Angulars区域之外的代码引起的

明确地运行更改检测

contructor(private cdRef:ChangeDetectorRef) {}

someMethodCalledFromOutside() {
  // code that changes properties in this component 
  this.cdRef.detectChanges();
}
contructor(private zone:NgZone) {}

someMethodCalledFromOutside() {
  this.zone.run(() => {
  // code that changes properties in this component 
  });
}
运行代码,明确修改Angulars区域内的组件属性

contructor(private cdRef:ChangeDetectorRef) {}

someMethodCalledFromOutside() {
  // code that changes properties in this component 
  this.cdRef.detectChanges();
}
contructor(private zone:NgZone) {}

someMethodCalledFromOutside() {
  this.zone.run(() => {
  // code that changes properties in this component 
  });
}
//更改此组件中属性的代码
不仅更改当前组件的属性,而且还导致其他组件的更改(如
this.router.navigate()
,调用其他组件方法的方法引用)时,
区域
方法更合适,因为
区域.run()
在Angulars区域内执行代码,您不需要明确地注意每个组件中的更改检测,因为此调用可能会发生更改

如果您使用
函数(…)
而不是
()=>
,则可能会在角度组件内部的代码中使用
,出现意外行为

有关更多详细信息,请参见我对类似问题的回答

更新

export class ViewManagerComponent {
    constructor(private zone:NgZone,private cdRef:ChangeDetectorRef) {
      self = this;
    }
    view = "page";

     @Output() renderView(type){
        // type is 'page'
        console.log(self.view)
        self.zone.run(() => {
            // type is 'page'
            console.log(self.view)
            self.view = type;
            // type is 'page1'
            console.log(self.view)
        });
        // type is 'page1'
        console.log(self.view)
        self.cdRef.detectChanges();
    };

}

谢谢我做了更改,第一次尝试了
this.zone.run
,但没有成功(没有错误)。然后我尝试了
cfRef.detectChanges()
,首先抱怨它不是一个提供者。我添加到
app.module
,然后得到以下错误:
view manager.component.ts:30 Uncaught TypeError:this.cdRef.detectChanges不是一个函数(…)
可能是因为
this
没有像我的回答中提到的那样指向当前组件实例。我链接到的答案应该为我修改代码提供了一个解决方案。请看上面。我在跟踪前后放置了几个控制台,
这个
似乎范围正确。你为什么不把
@Output()renderView=function(type){
改为
@Output()renderView(type){
?如果你有错误消息,请在你的问题中添加错误消息。