React CollectionView

The second view we will define is the view that will be used to render the entire ClickableItemArray. As mentioned earlier, React is similar to Backbone, in that we will define a view for every individual array item (ItemView), and then another view for the whole collection. This view will be named ItemCollectionView, and will use two interfaces as follows:

export interface IClickableItem { 
    Id: number; 
    DisplayName: string; 
} 
 
export interface IItemCollectionViewProps { 
    title: string, 
    items: IClickableItem[], 
    SelectedItem: IClickableItem; 
}; 

Here, we have defined an interface for each of our array items named IClickableItem that has the Id and DisplayName properties. Our second interface is named IItemCollectionViewProps, and defines the properties that our collection view will need. The Title property will contain "Please select", the items property will contain our array, and the SelectedItem property will contain the currently selected item. Note that React components are always created by extending React.Component using generic syntax and passing in a type that defines the properties of the component. This means that we cannot simply create a property on a React component and expect that it will be part of the props property. Let's take a look at the definition of this view as follows:

export class ItemCollectionView extends 
    React.Component<IItemCollectionViewProps, {}> { 
    // SelectedItem: IClickableItem; 
    // ^^ properties cannot be included like this. 
    constructor(input: IItemCollectionViewProps) { 
        super(input); 
        this.itemSelected = this.itemSelected.bind(this); 
        // ^^ this is functionally equivalent to below : 
        // _.bindAll(this, 'itemSelected'); 
    } 
 
    ... other code 
} 

Here, we have defined a class named ItemCollectionView that extends React.Component. Again, the generic syntax for React components requires two arguments, an object describing the properties of the view, and an object describing its initial state. As we are passing the IItemCollecitonViewProps interface in the generic syntax, we know that this React component will end up having a Title property, an items property, and a SelectedItem property. The constructor calls super, as seen previously, and then binds the execution context of the itemSelected function to the instance of the class. As noted before, the underscore function bindAll is a functional equivalent.

Let's now take a look at the render function, as follows:

render() { 
    let _this = this; 
 
    let buttonNodes = 
        this.props.items.map(function (item) { 
            return ( 
                <ItemView 
                   onItemClicked={_this.itemSelected} 
                   DisplayName={item.DisplayName} 
                   Id={item.Id}  
               /> 
            ); 
        }); 
 
    return <div> 
        <h1>{this.props.title}</h1> 
        <ul> 
            {buttonNodes} 
        </ul> 
        <div>Selected Item : 
            {this.props.SelectedItem.Id} - 
            {this.props.SelectedItem.DisplayName}</div> 
    </div>; 
} 

Here, we start our render function with the age-old JavaScript trick of defining a local variable named _this, which is set to this. The reason that we are doing this, is so that we can refer to the instance of the ItemCollectionView class a little later. The render function is divided into two sections.

The first section is the definition of a variable name, buttonNodes, which calls the map function on the items property, as seen in the call to this.props.items.map. This map function will loop through each item in the items array, and return an HTML snippet. The snippet returned is an HTML element named ItemView. This element name is the same as the class name of the ItemView class that we defined earlier. This element has an HTML attribute named onItemClicked, and then the DisplayName and Id attributes that the ItemView needs. The onItemClicked property is using the local variable, _this, to pass the itemSelected function as a callback function to ItemView. The itemSelected function of ItemCollectionView will therefore be invoked (through the callback) when an ItemView is clicked.

The second section of the render function returns the HTML snippet for the entire ItemCollectionView. This consists of an <h1> tag, which renders the title property via the {this.props.title} syntax. The next tag is a <ul> tag, and, within this, the {buttonNodes} variable. This HTML snippet, therefore, will include the results of our map function as defined by the buttonNodes variable. In this way, React allows us to use any TypesScript variable or function within our HTML templates in a simple and intuitive manner. The final part of this HTML snippet will render the currently selected item inside a <div> tag.

There is one more function that we need to define in this ItemCollectionView class, as follows:

itemSelected(item: IClickableItem) { 
    this.props.SelectedItem.Id = item.Id; 
    this.props.SelectedItem.DisplayName = item.DisplayName; 
 
    this.setState({}); 
} 

Here, we have defined the itemSelected function, which will be used as the callback when an ItemView is clicked. This function has a single parameter named item, of type IClickableItemThe function signature, therefore, matches the definition of the onItemClicked function of the ItemModel that we used to render each element of the collection. This function sets the value of the Id and DisplayName properties of the internal property named SelectedItem to match the incoming values. Again, to reference an internal property of a particular view, we must use the props property. Finally, this function calls the react function named setState with an empty object. This call to setState will rerender the entire view to the DOM.

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

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