You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: public/docs/ts/latest/guide/component-communication.jade
+106-1Lines changed: 106 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -588,10 +588,115 @@ figure.image-display
588
588
figure.image-display
589
589
img(src="/resources/images/devguide/component-communication/job-stolen-ui.png"alt="The job is stolen")
590
590
591
+
:marked
592
+
.alert.is-important
593
+
:marked
594
+
After a short by-pass (in the next scenario), we'll go on with the code we created in this scenario, so it is worth to make a backup
595
+
so that we can return to it easily.
596
+
591
597
:marked
592
598
## #9: Preventing stealth — using multiple facades
593
599
594
-
_Content_
600
+
Let's fix the issue with `JobService`! If we'd have two separate facades, one for `HeroJobBoard` and another for `InvitedHero`, we would not have this issue.
601
+
There are several ways to create two facades that use the same service object in the background. One way is to create two objects — each with the appropriate
602
+
facade —, and aggregate the singleton `JobService` instance with them. Implictly, these objects would expose only these `JobService` operations that are
603
+
required by their facade.
604
+
605
+
We will apply this method — with a little twist. We are going to leverage on two great TypeScript features:
1. TypeScript allows to use classes as if those were interfaces (more details [here](http://www.typescriptlang.org/Handbook#classes-advanced-techniques))
608
+
609
+
Here is the revised map of object communication. It leverages the refactored version of `JobService`, which now provides two facades,
610
+
`JobBoardFacade` and `InvitedHeroFacade`, respectively:
611
+
612
+
figure.image-display
613
+
img(src="/resources/images/devguide/component-communication/job-service-facades.png"alt="Communication through new facades")
614
+
615
+
:marked
616
+
Now let's see how these changes are represented in the code of `JobService`:
Although our suggested convention is to create one class per file — as treated in [Dependency Injection's Appendix](./dependency-injection.html#appendix-why-we-recommend-one-class-per-file)
623
+
— this code is an exception for the sake of easier discussion.
624
+
625
+
:marked
626
+
We declare `JobBoardFacade` and `InvitedHeroFacade` as abstract classes, and mark all of their operations as `abstract`. We altered the definitions of
627
+
`jobPostEvent` and `jobAssignedEvent` from a property getter to a function, since property getters cannot be abstract.
628
+
629
+
Just as many "curly brace" languages, TypeScript does not support multiple inheritance. Of course, it supports implementing multiple interfaces. We utilize the
630
+
TypeScript feature that it can handle classes as if those were interfaces: we declare `JobService` so that it _implements_ both `JobBoardFacade` and `InvitedHeroFacade`.
631
+
632
+
To make `HeroJobBoard` use `JobBoardFacade` and `InvitedHero` to work with `InvitedHeroFacade`, we need to change the constructors of these classes:
Evidently, we need to rename the local `jobService` property names in `HeroJobBoard` to `jobBoardFacade`, and in `InvitedHero` to `heroJobFacade` to
654
+
make the code sample work.
655
+
656
+
:marked
657
+
We have one more task to complete: we have to change dependency injection so that a _singleton_ `JobService` instance will be injected to the single
658
+
instance of `HeroJobBoard` and the multiple instances of `InvitedHero`. We'll do this by changing the `directives` annotation property on `HeroJobBoard`:
Right at the very beginning of the module, we create the single `JobService` instance, `jobService`. Because `JobService` implements both
681
+
`JobBoardFacade` and `InvitedHeroFacade`, we can configure the injector to use the single instance of `jobService` to represent both facades.
682
+
To achive this, we utilize the `provide()` function with the `useValue` configuration property.
683
+
684
+
### Why we cannot use `stealJob()` now
685
+
686
+
Now, the `InvitedHeroFacade` does not offer the `assign()` method, so when you try to compile the `invited-hero.ts` file, the TypeScript compiler raises an error:
687
+
688
+
code-example(language='text').
689
+
src/app/invited-hero.ts(114,28): error TS2339: Property 'assign' does not exist on type 'InvitedHeroFacade'.
690
+
691
+
:marked
692
+
When we work with an editor that has IntelliSense (Such as Sublime or Visual Studio Code), we cannot find `assign()` on the list of available members for
So, using separate facades to expose the services of the singleton `JobService` objects helped us to prevent issues coming from a flaw in the component design.
595
700
596
701
## #10: Broadcasting messages — parent and child communicates with an unrelated component
0 commit comments