我有两个UI成分,
Tab3Page:保存数据
Tab2Page:加载数据
Tab2Page被注入到Tab3Page
当数据通过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();
}
}
以下是组件Tab2Page
@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');
}
}
数据通过组件选项卡2Page中的pics变量以Html格式绑定,如下所示
<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>
**UPDATE尝试使用ChangeDetectorRef应用建议的解决方案,但我在浏览器事件中遇到以下错误,尽管编译成功。
core.js:9110 ERROR Error: Uncaught (in promise): NullInjectorError: StaticInjectorError(AppModule)[IonItemOption -> ChangeDetectorRef]:
StaticInjectorError(Platform: core)[IonItemOption -> ChangeDetectorRef]:
NullInjectorError: No provider for ChangeDetectorRef!
NullInjectorError: StaticInjectorError(AppModule)[IonItemOption -> ChangeDetectorRef]:
StaticInjectorError(Platform: core)[IonItemOption -> ChangeDetectorRef]:
NullInjectorError: No provider for ChangeDetectorRef!
at NullInjector.get (core.js:778)
at resolveToken (core.js:2564)
at tryResolveToken (core.js:2490)
at StaticInjector.get (core.js:2353)
at resolveToken (core.js:2564)
at tryResolveToken (core.js:2490)
at StaticInjector.get (core.js:2353)
at resolveNgModuleDep (core.js:26403)
at NgModuleRef_.get (core.js:27491)
at resolveNgModuleDep (core.js:26403)
at resolvePromise (zone-evergreen.js:797)
at resolvePromise (zone-evergreen.js:754)
at zone-evergreen.js:858
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at drainMicroTaskQueue (zone-evergreen.js:559)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
at invokeTask (zone-evergreen.js:1603)
由于上面的错误建议添加ChangeDetectorRef作为提供程序,因此尝试在模块文件中执行此操作。但在编译时再次出错,因为ChangeDetectorRef是不支持的提供程序类型。
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
RouterModule.forChild([{ path: '', component: Tab2Page }])
],
declarations: [Tab2Page, SafeurlPipe],
providers: [ChangeDetectorRef]
})
export class Tab2PageModule {}
[ng] ℹ 「wdm」: Compiling...
[ng]
[ng] ERROR in src/app/tab2/tab2.module.ts(17,15): error TS2322: Type 'typeof ChangeDetectorRef' is not assignable to type 'Provider'.
[ng] Type 'typeof ChangeDetectorRef' is not assignable to type 'TypeProvider'.
[ng] Cannot assign an abstract constructor type to a non-abstract constructor type.
[ng]
[ng] Date: 2019-08-12T04:20:20.951Z - Hash: 99468e1aeee0ce99f6f1
[ng] 105 unchanged chunks
**更新(修复)无法使用组件依赖注入完成。但是,能够使用组件之间的共享数据服务并使用rxjs“主题”和订阅来实现相同的预期结果。执行过程可以在下面的Angular留档中找到。它需要一点时间来完成,但对于动态UI渲染非常强大。
https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service
我仍然有点担心为什么我不能在ionic应用程序中使用ChangeDetectorRef,以防我将来可能需要它。
注入ChangeDetectorRef:
constructor(
private cdr: ChangeDetectorRef,
) {}
然后触发更改事件:
async updatePics() {
//do something
this.cdr.detectChanges();
}
您不需要使用changeDetectorRef来解决您的问题。这里的问题是,在您的选项卡3页面中,您试图注入选项卡2页面,并使用它调用选项卡2页面中的函数。您不能将组件直接注入其他组件并使用它们。查看文档以了解组件如何相互交互。您可以使用ViewChild调用updatePics()
在选项卡3页中,从构造函数中删除选项卡2页,然后添加ViewChild(从角/芯导入)
表3.第页。ts
export class Tab3Page implements OnInit {
pics: Picture[] = [];
@ViewChild('tab2') tab2: Tab2Page;
constructor(public fileservice: FileService) {}
ngOnInit() {
console.log('ng init');
this.pics = PICS;
}
saveContent(pic: Picture) {
this.fileservice.savefile(pic);
this.tab2.updatePics();
}
}
在html中添加模板变量,以便查看子级可以访问组件。
tab3.page.html
<app-tab2 #tab2 [pics]="pics"></app-tab2>
还有一种方法可以更新数据。由于pics是从选项卡3页传递的输入,只需将updatePics从选项卡2页移动到选项卡3页并调用即可。
表3.第页。ts
export class Tab3Page implements OnInit {
pics: Picture[] = [];
constructor(public fileservice: FileService) {}
ngOnInit() {
console.log('ng init');
this.pics = PICS;
}
saveContent(pic: Picture) {
this.fileservice.savefile(pic);
this.updatePics();
}
async updatePics() {
this.pics = await this.fileservice.getSavedPics();
}
}
Angular 2的DI系统(大部分)通过来控制。 具体来说是providers 和declarations数组。 (declarations是我们放置组件,管道和指令的地方;providers 是我们提供服务的地方) 例如: 这看起来很简单,但读者会想知道Angular 2如何知道如何构建ChatWidget 。如果ChatWidget是一个字符串或一个简单的函数怎么办? Angular 2假设
问题内容: 我已经阅读了AngularJS文档,但仍然没有我知道的答案。 为什么要使用两次?一次作为数组元素,第二次作为函数参数。 问题答案: 如果缩小此代码: 您将以(类似)结尾: 由于参数名称丢失,因此Angular将无法注入依赖项。 另一方面,如果您将此代码最小化: 您将以: 参数名称可用:Angular的DI可操作。
如何使用新的Angular 2.3组件继承在子组件和父组件之间共享依赖注入? 例如,我想将AlertService移到父组件中,并将TraingCompanyService留在派生组件中 当前组件 重构组件 (V1) 在派生类的构造函数中调用Super之前,必须先调用它 重构组件(V2) 类培训公司编辑组件错误地扩展基类 BaseAdminEditComponent,类型具有单独的私有属性声明“a
我有一个问题加载类到Angular组件。很长一段时间以来,我一直试图解决这个问题;我甚至尝试将它加入到一个文件中。我拥有的是: 一个pplication.ts 服务/名称服务。ts 我一直收到一条错误消息,说。 有人能帮我发现代码的问题吗?
我有以下课程: 这只是其中一个例子,我有一些类似的其他类,我将它们作为依赖注入到其他类中。但是它使我的SchemaFetcher类像一个单例,我不断地向它的每一个方法传递模式定义。这似乎是非常程序化的,我想实际上使模式定义成为数据库模式获取类的实例变量,但在这种情况下,我将无法将模式获取对象注入到我的验证器类中,相反,我应该这样做 但这使我与fetcher紧密耦合,这就是为什么我想首先使用依赖注入