У меня есть два компонента (которые могут быть сделаны реализациями общего базового класса / интерфейса).
Автоматический механизм внедрения зависимостей c для конструкторов компонентов не работает для моего случая, когда общий дочерний элемент компонент этих двух компонентов должен иметь доступ к своему указанному c родительскому компоненту.
Что мне нужно сделать, чтобы по-прежнему иметь один тип подкомпонента для обоих родительских типов?
Исходный код
компонент просмотра часов
import { Component, OnInit, Input } from '@angular/core';
import { Clock } from "../clock";
import { ClocksFlowViewComponent } from "../clocks-flow-view/clocks-flow-view.component";
import { ClocksDataGridComponent } from '../clocks-data-grid/clocks-data-grid.component';
@Component({
selector: 'app-clock-view',
templateUrl: './clock-view.component.html',
styleUrls: ['./clock-view.component.scss']
})
export class ClockViewComponent implements OnInit {
@Input() clock: Clock;
constructor(
private parentCollectionView: ClocksFlowViewComponent
) { }
ngOnInit() {
}
onClicked(c: Clock)
{
for (let c2 of this.parentCollectionView.clocks)
{
c2.selected = false;
}
c.selected = true;
}
}
компонент сетки данных часов
import { Component, OnInit } from '@angular/core';
import { Clock } from '../clock';
import { ClockService } from "../clock.service";
@Component({
selector: 'app-clocks-data-grid',
templateUrl: './clocks-data-grid.component.html',
styleUrls: ['./clocks-data-grid.component.scss']
})
export class ClocksDataGridComponent implements OnInit {
static selectedClock : Clock | null;
clocks : Clock[];
constructor(
private clockService: ClockService
) {
}
ngOnInit() {
this.getClocks();
}
getClocks(): void
{
this.clockService.getClocks()
.subscribe(clocks => this.clocks = clocks);
}
}
компонент просмотра часов
import { Component, OnInit } from '@angular/core';
import { Clock } from '../clock';
import { ClockService } from "../clock.service";
@Component({
selector: 'app-clocks-flow-view',
templateUrl: './clocks-flow-view.component.html',
styleUrls: ['./clocks-flow-view.component.scss']
})
export class ClocksFlowViewComponent implements OnInit {
static selectedClock : Clock | null;
clocks : Clock[];
constructor(
private clockService: ClockService
) {
}
ngOnInit() {
this.getClocks();
}
getClocks(): void
{
this.clockService.getClocks()
.subscribe(clocks => this.clocks = clocks);
}
}
Шаблоны
В настоящее время шаблоны для сетки данных и представления потока одинаковы:
<div *ngFor="let clock of clocks">
<app-clock-view [clock]="clock"></app-clock-view>
</div>
Но они будут отличаться.
Шаблон компонента просмотра часов:
<div class="clock-view" (click)="onClicked(clock)" [class.selected]="clock.selected">
<h2>{{clock.id}}. {{clock.tag}}</h2>
<textarea [(ngModel)]="clock.tag" placeholder="clock tag here" class="clock-tag-textarea"></textarea>
</div>
При посещении http://localhost: 4200 / data-grid я получаю эту ошибку в консоли Chrome:
core.js:38781 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
ClocksDataGridComponent.html:4 ERROR NullInjectorError: StaticInjectorError(AppModule)[ClockViewComponent -> ClocksFlowViewComponent]:
StaticInjectorError(Platform: core)[ClockViewComponent -> ClocksFlowViewComponent]:
NullInjectorError: No provider for ClocksFlowViewComponent!
at NullInjector.get (http://localhost:4200/vendor.js:39072:27)
at resolveToken (http://localhost:4200/vendor.js:53990:24)
at tryResolveToken (http://localhost:4200/vendor.js:53916:16)
at StaticInjector.get (http://localhost:4200/vendor.js:53766:20)
at resolveToken (http://localhost:4200/vendor.js:53990:24)
at tryResolveToken (http://localhost:4200/vendor.js:53916:16)
at StaticInjector.get (http://localhost:4200/vendor.js:53766:20)
at resolveNgModuleDep (http://localhost:4200/vendor.js:64953:29)
at NgModuleRef_.get (http://localhost:4200/vendor.js:66019:16)
at resolveDep (http://localhost:4200/vendor.js:66550:45)
View_ClocksDataGridComponent_1 @ ClocksDataGridComponent.html:4
logError @ core.js:45546
handleError @ core.js:6066
(anonymous) @ core.js:41058
invoke @ zone-evergreen.js:359
run @ zone-evergreen.js:124
runOutsideAngular @ core.js:39572
tick @ core.js:41055
(anonymous) @ core.js:40893
invoke @ zone-evergreen.js:359
onInvoke @ core.js:39699
invoke @ zone-evergreen.js:358
run @ zone-evergreen.js:124
run @ core.js:39511
next @ core.js:40890
schedulerFn @ core.js:35336
__tryOrUnsub @ Subscriber.js:185
next @ Subscriber.js:124
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:35298
checkStable @ core.js:39642
onHasTask @ core.js:39719
hasTask @ zone-evergreen.js:411
_updateTaskCount @ zone-evergreen.js:431
_updateTaskCount @ zone-evergreen.js:264
runTask @ zone-evergreen.js:185
drainMicroTaskQueue @ zone-evergreen.js:559
Promise.then (async)
scheduleMicroTask @ zone-evergreen.js:542
scheduleTask @ zone-evergreen.js:381
scheduleTask @ zone-evergreen.js:211
scheduleMicroTask @ zone-evergreen.js:231
scheduleResolveOrReject @ zone-evergreen.js:845
then @ zone-evergreen.js:955
bootstrapModule @ core.js:40600
./src/main.ts @ main.ts:11
__webpack_require__ @ bootstrap:79
0 @ main.ts:18
__webpack_require__ @ bootstrap:79
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.js:1
ClocksDataGridComponent.html:4 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 2, nodeDef: {…}, elDef: {…}, elView: {…}}
View_ClocksDataGridComponent_1 @ ClocksDataGridComponent.html:4
logError @ core.js:45546
handleError @ core.js:6071
(anonymous) @ core.js:41058
invoke @ zone-evergreen.js:359
run @ zone-evergreen.js:124
runOutsideAngular @ core.js:39572
tick @ core.js:41055
(anonymous) @ core.js:40893
invoke @ zone-evergreen.js:359
onInvoke @ core.js:39699
invoke @ zone-evergreen.js:358
run @ zone-evergreen.js:124
run @ core.js:39511
next @ core.js:40890
schedulerFn @ core.js:35336
__tryOrUnsub @ Subscriber.js:185
next @ Subscriber.js:124
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:35298
checkStable @ core.js:39642
onHasTask @ core.js:39719
hasTask @ zone-evergreen.js:411
_updateTaskCount @ zone-evergreen.js:431
_updateTaskCount @ zone-evergreen.js:264
runTask @ zone-evergreen.js:185
drainMicroTaskQueue @ zone-evergreen.js:559
Promise.then (async)
scheduleMicroTask @ zone-evergreen.js:542
scheduleTask @ zone-evergreen.js:381
scheduleTask @ zone-evergreen.js:211
scheduleMicroTask @ zone-evergreen.js:231
scheduleResolveOrReject @ zone-evergreen.js:845
then @ zone-evergreen.js:955
bootstrapModule @ core.js:40600
./src/main.ts @ main.ts:11
__webpack_require__ @ bootstrap:79
0 @ main.ts:18
__webpack_require__ @ bootstrap:79
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.js:1
client:52 [WDS] Live Reloading enabled.
Проблема, вкратце выражается, что внедрение зависимости в конструкторы d oes не работает с типами union (в моем случае ClocksFlowViewComponent | ClocksDataGridComponent
). Проблема в том, что если я добавляю тип объединения, он выдает ошибку времени выполнения, и если я ставлю два параметра, для одного он тоже не срабатывает с ошибкой времени выполнения, и я не знаю наиболее правильной альтернативы.
...
constructor(
private parentCollectionView: ClocksFlowViewComponent
) { }
...
Репозиторий GitHub здесь .
Это мой первый день с Angular. Спасибо.
Обновление 1
Я пытаюсь достичь с помощью метода onClicked
в компоненте clock-view
. Я хочу знать, какой clock-view
выбран. В будущем мне может понадобиться сложный механизм выбора (множественный выбор, Ctrl, Shift, прямоугольник с резинкой, щелчок мыши).