无法从另一个组件

时间:2017-07-17 19:41:13

标签: angular typescript angular2-components angular2-changedetection

我有以下情况:

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

所以这个概念是在promise向我的主题发送一些价值之后我需要将someValue推到菜单中,直到这一点它确定所有数据都可以到达,但我需要重新渲染视图以便& #34; someValue中"显示在视图上。但它什么也没做,当我将this._cdRef.markForCheck()更改为this._cdRef.detectChanges()并将其放在tryCatch上时,它返回Attempt to use a destroyed view: detectChanges。我找不到用someValue渲染菜单的方法。

这两个组件在ChangeDetection树上处于同一级别

3 个答案:

答案 0 :(得分:1)

试试ApplicationRef.tick()。这是“始终在工作”的解决方法。

import { ApplicationRef } from '@angular/core';

export SomeComponent {
    constructor(private appRef: ApplicationRef) {}

    public thisShouldCauseChangeDetection(): void {
        this.appRef.tick();
    }
}

此处提出了类似的问题:Trigger update of component view from service - No Provider for ChangeDetectorRef

有关ApplicationRef的更多信息:https://angular.io/api/core/ApplicationRef

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

答案 1 :(得分:1)

我对此案的解决方案是Maciej Treder的建议, 他说:

&#39;针对您的问题的最佳解决方案是使用Component <-> Service <-> Component通讯:https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service&#39;

因此,我创建了一项服务,该服务可以收听@PermissionModule所做的更改并将更改事件发送到@MenuComponent,因为我可以将vales推送到menus }数组并呈现视图,没有.tick().detectChanges()

的ServiceComponent

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

答案 2 :(得分:0)

而不是在this.menus内推送价值,尝试类似这样的事情

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