Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Angular:NullInjectorError:ChangeDetectorRef中强制更新依赖项注入组件_Javascript_Angular_Ionic Framework - Fatal编程技术网

Javascript 如何在Angular:NullInjectorError:ChangeDetectorRef中强制更新依赖项注入组件

Javascript 如何在Angular:NullInjectorError:ChangeDetectorRef中强制更新依赖项注入组件,javascript,angular,ionic-framework,Javascript,Angular,Ionic Framework,我有两个UI组件 表3页面:保存数据 表2页面:加载数据 将TAB2页注入TAB3页 当数据通过Tabd3Page保存时,我尝试在Tab2Page中自动加载数据 目前,当我在tab3中保存数据时,tab2不会自动更新,直到我手动刷新页面浏览器。有没有办法强制呈现像react as SetState()中那样的页面 以下是组件选项卡3页 @Component({ selector: 'app-tab3', templateUrl: 'tab3.page.html', styleUrls

我有两个UI组件

表3页面:保存数据

表2页面:加载数据

将TAB2页注入TAB3页

当数据通过Tabd3Page保存时,我尝试在Tab2Page中自动加载数据

目前,当我在tab3中保存数据时,tab2不会自动更新,直到我手动刷新页面浏览器。有没有办法强制呈现像react as SetState()中那样的页面

以下是组件选项卡3页

@Component({
  selector: 'app-tab3',
  templateUrl: 'tab3.page.html',
  styleUrls: ['tab3.page.scss']
})
export class Tab3Page implements OnInit {
  pics: Picture[] = [];
  constructor(public fileservice: FileService, private tab2: Tab2Page) {}

  ngOnInit() {
    console.log('ng init');
    this.pics = PICS;
  }

  saveContent(pic: Picture) {
    this.fileservice.savefile(pic);
    this.tab2.updatePics();
    this.tab2.refreshComponent();
  }
}
下面是组件选项卡2页

@Component({
  selector: 'app-tab2',
  templateUrl: 'tab2.page.html',
  styleUrls: ['tab2.page.scss']
})
export class Tab2Page implements
OnInit,
OnChanges {
  @Input() pics: Picture[];

  constructor(public fileservice:FileService, private cdr: ChangeDetectorRef) { }
  // constructor(public fileservice: FileService) { }

  ngOnInit() {
    console.log('ng init');
    this.updatePics();
  }

  ngOnChanges(changes: SimpleChanges) {
    // changes.prop contains the old and the new value...
    console.log('changes', changes);
  }

  async updatePics() {
    this.pics = await this.fileservice.getSavedPics();
  }

  refreshComponent() {
    this.cdr.detectChanges();
    console.log('component refresh triggred');
  }

}
<ion-list *ngFor="let pic of pics">
  <ion-item-sliding>
    <ion-item>
    <ion-grid>
      <ion-row>
        <ion-col size="3">
          <ion-thumbnail>
            <img [src]="(pic.url | safeurl)">
          </ion-thumbnail>
        </ion-col>
        <ion-col size="9">
          <ion-label>{{pic.name}}</ion-label>
        </ion-col>
      </ion-row>  
    </ion-grid>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option>Delete</ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>
数据通过组件Tab2Page中的pics变量以Html格式绑定,如下所示

@Component({
  selector: 'app-tab2',
  templateUrl: 'tab2.page.html',
  styleUrls: ['tab2.page.scss']
})
export class Tab2Page implements
OnInit,
OnChanges {
  @Input() pics: Picture[];

  constructor(public fileservice:FileService, private cdr: ChangeDetectorRef) { }
  // constructor(public fileservice: FileService) { }

  ngOnInit() {
    console.log('ng init');
    this.updatePics();
  }

  ngOnChanges(changes: SimpleChanges) {
    // changes.prop contains the old and the new value...
    console.log('changes', changes);
  }

  async updatePics() {
    this.pics = await this.fileservice.getSavedPics();
  }

  refreshComponent() {
    this.cdr.detectChanges();
    console.log('component refresh triggred');
  }

}
<ion-list *ngFor="let pic of pics">
  <ion-item-sliding>
    <ion-item>
    <ion-grid>
      <ion-row>
        <ion-col size="3">
          <ion-thumbnail>
            <img [src]="(pic.url | safeurl)">
          </ion-thumbnail>
        </ion-col>
        <ion-col size="9">
          <ion-label>{{pic.name}}</ion-label>
        </ion-col>
      </ion-row>  
    </ion-grid>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option>Delete</ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>
由于上面的错误建议将ChangeDetectorRef添加为提供程序,因此尝试在模块文件中执行此操作。但在编译中再次出现错误,因为ChangeDetectorRef的提供程序类型不受支持

@NgModule({
  imports: [
    IonicModule,
    CommonModule,
    FormsModule,
    RouterModule.forChild([{ path: '', component: Tab2Page }])
  ],
  declarations: [Tab2Page, SafeurlPipe],
  providers: [ChangeDetectorRef]
})
export class Tab2PageModule {}
**更新(修复) 无法使用组件依赖项注入完成此操作。然而,通过在组件之间使用共享数据服务以及使用rxjs“主题”和订阅,我们能够实现相同的预期结果。在下面的角度文档中可以找到这样做的过程。它需要一点来包装它的头部,但对于动态UI呈现的东西来说非常强大


我仍然有点担心为什么我不能在ionic应用程序中使用ChangeDetectorRef,以防将来需要它。

Inject
ChangeDetectorRef

  constructor(
    private cdr: ChangeDetectorRef,
  ) {}
然后触发更改事件:

async updatePics() {
    //do something
    this.cdr.detectChanges();
}

对于您的问题,您不需要使用
changeDetectorRef
。这里的问题是,在
Tab3Page
中,您试图插入
Tab2Page
,并使用它调用
Tab2Page
中的函数。不能直接在其他组件中插入组件并使用它们。请参见,以了解组件如何相互交互。您可以使用调用
updatePics()

Tab3Page
中,从构造函数中删除
Tab2Page
,并添加ViewChild(从
@angular/core
导入)

表3.page.ts

导出类Tab3Page实现OnInit{
图片:图片[]=[];
@ViewChild('tab2')tab2:Tab2Page;
构造函数(公共文件服务:文件服务){}
恩戈尼尼特(){
console.log('nginit');
this.pics=pics;
}
保存内容(图:图片){
这个.fileservice.savefile(pic);
this.tab2.updatePics();
}
}
在html中添加模板变量,以便
ViewChild
可以访问该组件

tab3.page.html


还有一种方法可以更新数据。由于
pics
是从
Tab3Page
传递的
Input
,只需将
updatePics
Tab2Page
移动到
Tab3Page
并调用它即可

表3.page.ts

导出类Tab3Page实现OnInit{
图片:图片[]=[];
构造函数(公共文件服务:文件服务){}
恩戈尼尼特(){
console.log('nginit');
this.pics=pics;
}
保存内容(图:图片){
这个.fileservice.savefile(pic);
这个.updatePics();
}
异步更新{
this.pics=等待this.fileservice.getSavedPics();
}
}

谢谢,但我在使用ChangeDetectorRef时出错,看起来它与ionic angular有一些问题?您好,谢谢您给我一些建议。我不能使用查看子视图的想法,因为这些选项卡位于不同的路径中,并且它们各自的路径具有不同的UI组件。下一个建议是更新Tab3page UI中的pics数据,而不是Tab2Page UI。我不得不选择使用RxJS“Subject”的另一种方式,这在angular文档中提到过。拍摄对象和观察对象都很吸引人,我仍在为之绞尽脑汁。我想知道为什么“ChangeDetectorRef”会出现运行时错误。我的第二个建议假设您正在使用
@输入将
pics
Tab3Page
传递到
Tab2Page
。这样,当您在
Tab3Page
中更新
pics
时,
Tab2Page
中的
@Input
也会得到更新。我明白了,我的缺点是变量命名相同。在我的用例中,这两个页面具有不同的“pics”数据状态。Tab2中的数据实际上是Tab3中数据的子集。Tab2仅包括用户从Tab3中的数据项中选择的项。