无法从另一个组件强制在 agular2 中渲染



我有以下情况:

组件@permissions 此组件有一个按钮,可以触发一个简单的承诺,并在我的另一个组件上设置一个值@MenuComponent

export class Permissions {
constructor(private _menu: MenuComponent, private _api: ApiService) {}
btnAction(){
this._api.getDataID(item.project_name, 'usersbyID', userID).then((data: any) => {
this._menu.checkPerm(JSON.parse(data.permissions).description);
});
}
}

返回的内容并不重要,但它是一个简单的 JSON。

在我的其他组件@MenuComponent

@Component({
// ..another configuration non relevant
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MenuComponent implements OnInit {
menus = []
menuPermisson: any;
menuObservable = new Subject();
constructor(private _cdRef: ChangeDetectorRef) {
this.menuObservable.subscribe(value => {
this.menuPermisson = value;
this.reloadAll();
});
}
reloadAll() {
this.menus.push('someValue');
this._cdRef.markForCheck();
}
checkPerm(data) {
this.menuObservable.next(data);
}
}

所以这个概念是在承诺向我的主题发送一些值之后,我需要将 someValue 推送到菜单,直到此时所有数据都到达那里没问题,但我需要重新呈现视图,以便"someValue"显示在视图上。 但是它什么也没做,当我将this._cdRef.markForCheck()更改为this._cdRef.detectChanges()并将其放在 tryCatch 上时,它会返回Attempt to use a destroyed view: detectChanges.我找不到使用 someValue 呈现菜单的方法。

这两个组件在更改检测树上处于同一级别

尝试ApplicationRef.tick().这是"始终有效"的解决方法。

import { ApplicationRef } from '@angular/core';
export SomeComponent {
constructor(private appRef: ApplicationRef) {}
public thisShouldCauseChangeDetection(): void {
this.appRef.tick();
}
}

这里提出了类似的问题:从服务触发组件视图的更新 - 没有 ChangeDetectorRef 的提供程序

更多关于 应用参考: https://angular.io/api/core/ApplicationRef

解决您的问题的最佳方法是使用Component <-> Service <-> Component通信: https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

我对这种情况的解决方案是Maciej Treder的建议, 他说:

"解决您问题的最佳方法是使用Component <-> Service <-> Component沟通:https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service">

因此,我创建了一个服务,该服务侦听@PermissionModule所做的更改,并向@MenuComponent发送更改事件,我能够将 vales 推送到menus数组中并呈现视图,而无需.tick().detectChanges()

服务组件

@Injectable()
export class SharedServiceMenu {
// Observable string sources
private emitChangeSource = new Subject<any>();
// Observable string streams
changeEmitted$ = this.emitChangeSource.asObservable();
// Service message commands
emitChange(change: any) {
this.emitChangeSource.next(change);
}
constructor() { }
}

我想在哪里发送事件:

// ...irrelevant code constructor(private: _shared: SharedServiceMenu){} this._shared.emitChange(data);

我想听哪里发出的变化

// ... IrrelevantCode
constructor(private _shared: SharedServicesMenu){}
this._shared.changeEmitted$.subscribe((data) => {
//Do what ever you want with data emmited here
}, (err) => {
console.log(err);
}, () => {
console.log('Complete!');
});

与其在里面推值this.menus不如尝试这样的事情

reloadAll() { 
var tmp = this.menus.slice();
tmp.push('some valuue');
this.menus=tmp;
}

相关内容

  • 没有找到相关文章

最新更新