Angular2 从应用程序外部调用公开方法并丢失更改绑定

Angular2 Calling exposed method from outside app and loses change binding

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

app.component

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

公共服务

export class PublicService {

    constructor(
        private  _viewManager: ViewManagerComponent,
    ) {}

    CallMe(){
        this._viewManager.renderView('page1')
    }
}

LayoutManagerComponent

@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)
    };
}

所以想法是,当视图最初加载时,视图是空白的。然后,当我键入 angular.methods.CallMe() 时,它会将 view 变量修改为 page1,然后应该显示组件的 html。如果我控制 renderView 函数它被成功调用,只是视图没有改变。

----更新 - 仍然无法正常工作 ------

export class ViewManagerComponent {
    constructor(private zone:NgZone,private cdRef:ChangeDetectorRef) {

    }
    view = "page";

     @Output() renderView(type){
        // type is 'page'
        console.log(this.view)
        this.zone.run(() => {
            // type is 'page'
            console.log(this.view)
            this.view = type;
            // type is 'page1'
            console.log(this.view)
        });
        // type is 'page1'
        console.log(this.view)
        //cdRef errors: 
        //view-manager.component.ts:36 Uncaught TypeError: this.cdRef.detectChanges is not a function(…)
        this.cdRef.detectChanges();
    };

}

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

运行 显式更改检测

contructor(private cdRef:ChangeDetectorRef) {}

someMethodCalledFromOutside() {
  // code that changes properties in this component 
  this.cdRef.detectChanges();
}

运行 显式修改 Angulars 区域内组件属性的代码

contructor(private zone:NgZone) {}

someMethodCalledFromOutside() {
  this.zone.run(() => {
  // code that changes properties in this component 
  });
}

// code that changes properties in this component不仅改变当前组件的属性,而且还会引起其他组件的改变(如this.router.navigate(),调用方法引用的时候,zone方法更适合其他组件的方法),因为 zone.run() 在 Angulars 区域内执行代码,并且您不需要在每个组件中明确处理更改检测,因为此调用可能会发生更改。

如果您使用 function(...) 而不是 () =>,您可能会在 Angular 组件内的代码中使用 this 出现意外行为。

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

更新

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();
    };

}