3

我有一个公开的方法,我接触过window。此方法与 a 对话Component并修改我在模板中查看的变量。但是当我更改值时,*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)
    };
}

所以想法是,当视图最初加载时,视图是空白的。然后,当我键入时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();
    };

}
4

1 回答 1

3

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

显式运行变更检测

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

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

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

有关更多详细信息,另请参阅我对这个类似问题的回答Angular 2 - typescript 函数与外部 js 库的通信

更新

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

}
于 2016-10-11T05:43:14.297 回答