Angular2从外部调用暴露的方法,丢失了更改绑定

Angular2 Calling exposed method from outside app and loses change binding

本文关键字:绑定 外部调用 暴露 方法 Angular2      更新时间:2023-09-26

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

app.component

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

PublicService

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

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

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()在angular区域内执行代码,并且您不需要显式地在每个可能因此调用而发生更改的组件中进行更改检测。

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

参见我对这个类似问题的回答了解更多细节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();
    };
}