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();
};
}
我有一个 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();
};
}