Raising and consuming Domain Events

When a user clicks on a particular board in the board-list component, we can trap this event by adding a click handler in our board-list.component.html file as follows:

<div *ngFor="let board of boardList;"  
   class="col-sm-4 board-detail-clickable"  
   (click)="buttonClickedDetail(board)"> 

Here, we have added a (click) event handler on the outer <div> element that is generated for each of the boards in our board list. The click handler is named buttonClickedDetail, and has a single argument that is set to the current array element of the boardList array. The corresponding function in our board-list.component.ts file is as follows:

... existing imports ... 
import { BroadcastService } from '../services/broadcast.service'; 
 
... existing code ... 
export class BoardListComponent implements OnInit { 
 
    boardList: IBoard[] = []; 
 
    constructor(private boardService: BoardService, 
        private broadcastService: BroadcastService) { } 
 
    buttonClickedDetail(board: IBoard) { 
        this.broadcastService.broadcast( 
           'board-detail-clicked', board); 
    } 

Here, we have imported the BroadcastService as part of our existing import statements, and have also updated the constructor function to include a private variable named broadcastService that will hold the instance of the BroadcastService that is injected into this class instance. We have then defined a buttonClickedDetail function that will be invoked when the user clicks on the <div> element of the HTML. This function simply calls the broadcast function of the broadcastService instance with two arguments. The first argument corresponds to the key property that we have discussed previously, and is a simple string value of 'board-detail-clicked'. The second argument is the full board class that is the array element.

Our board-list component is now raising a Domain Event to indicate that a board has been clicked by the user, and that the application should show the details of this board.

We will implement the "listener" part of the Domain Event pattern in our secure component as follows:

export class SecureComponent implements IMediatorImpl, AfterViewInit { 
 
    constructor(private broadcastService: BroadcastService) { 
        _.bindAll(this, [`boardDetailClicked`]); 
          this.broadcastService.on( 
            'board-detail-clicked') 
          .subscribe(this.boardDetailClicked); 
    } 
 
    boardDetailClicked(value: IBroadcastEvent) { 
        console.log(`SecureComponent :  
            boardDetailClicked: ${JSON.stringify(value)}`); 
        this.rightScreen.setBoard(value.data); 
        this.mediator.moveToState(StateType.DetailPanel); 
    } 

Here, we have updated our constructor function to include a private variable named broadcastService, as we have seen previously. Within the constructor function, we make a call to the bindAll function of the underscore library, to bind the boardDetailClicked function to the correct instance of the this variable. Remember that when an event occurs on an HTML page, the context of this event is related to the page itself, and is not automatically related to the instance of the SecureComponent class that generated the page. The bindAll function corrects this context such that the instance of the SecureComponent that receives the event is retained when the event occurs.

Within our constructor function, we then call the on function of the BroacastService to register a function that will act as an event handler when the event occurs. The on function requires a single parameter, which is the name of the event itself, which, in this case, is set to 'board-detail-clicked'. As the on function of the BroadcastService returns an Observable, we must call the subscribe function to react to changes in the Observable. Instead of defining an anonymous function to be used with subscribe, we have used a class function instead, which is named boardDetailClicked.

The boardDetailClicked function receives a single parameter named value, which is of type IBroadcastEvent. Within this function, we are logging the contents of IBroadcastEvent to the console for debugging purposes, and then call a new function named setBoard on the rightscreen component. Remember that the rightscreen component is a ViewChild component, and, as such, allows us to directly call functions on the RightscreenComponent class itself. The function that we are calling is named setBoard, and will pass the data property of the Domain Event that we received. This data property is, in fact, an object that contains all of the data related to a single board.

Once we have called the setBoard function of the rightscreen component, we invoke the moveToState function of the Mediator class to transition our screen state from the MainPanel state to the DetailPanel state. This will initiate the screen animation, and display the detail panel. We will need to implement the setBoard function in the rightscreen component as follows:

export class RightscreenComponent implements OnInit { 
 
    board: IBoardExtended; 
 
    setBoard(value: IBoardExtended) { 
        console.log(`Rightscreen : setBoard received :  
            ${JSON.stringify(value, null, 4)}`); 
        this.board = value; 
    } 

Here, we have updated the RightscreenComponent class to include a local property named board, which is of type IBoardExtended. We have then defined the setBoard function, which accepts a value parameter of type IBoardExtended, and simply logs a message to the console before setting the internal board property to the incoming value.

If we run our application now, and click on a board, we will see this console.log message showing up in our Developer tools as follows:

Here, we can see that the RightscreenComponent has received a message using the BroadcastService that contains all of the information we need to render the detail panel for a particular board. It already includes both the sizes array and the types array that were loaded initially on the board-list component screen. With this information available, we can update the HTML file to render this information to our user.

Note that for the sake of brevity, we will not discuss the full HTML file here, as there are various elements and CSS classes at play in order to generate an aesthetically pleasing screen. Please refer to the sample code that is available for this chapter to view the related HTML and CSS files.

Once our HTML and CSS files are in place, our detail screen is as follows:

Here, the rightscreen component has been updated to show the full details of the selected board, with more information on the available sizes. With our board list and board detail screens completed, we can now look at filtering the board list from the sidenav component.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.98.13