How the controller sends data to view

In the previous paragraph, we have seen how to display the content view. However, the view should only be responsible for displaying data, and not for manipulation. Consequently, any work on data should be done in controller action and then passed to view.

The render() method in the action of the controller has a second parameter, which is an array whose keys are names of variables, and values are the content of these variables available in view context.

Now, let's move all data manipulation of our itemsList example in controller, leaving out just the code to format the output (such as HTML).

The following is the content of the actionItemsList() controller:

public function actionItemsList()
{
  $newsList = [
    [ 'title' => 'First World War', 'date' => '1914-07-28' ],
    [ 'title' => 'Second World War', 'date' => '1939-09-01' ],
    [ 'title' => 'First man on the moon', 'date' => '1969-07-20' ]
  ];

  return $this->render('itemsList', ['newsList' => $newsList]);
}

In views/news/itemsList.php, we only have the following code:

<?php // $newsList is from actionItemsList ?>
<table>
    <tr>
        <th>Title</th>
        <th>Date</th>
    </tr>
    <?php foreach($newsList as $item) { ?>
    <tr>
        <th><?php echo $item['title'] ?></th>
        <th><?php echo $item['date'] ?></th>
    </tr>
    <?php } ?>
</table>

Thus, we have correctly split the working of controller and view.

Example – create a controller to display the static news items list and details using the bootstrap template

Our next goal is to complete the news reader displaying details of single news in another page.

Since we are going to use the same data for list and detail, we will extract the $newsList data from action to a function, in order to be reused for more actions.

In NewsController, we will have the following code:

public function dataItems()
{
  $newsList = [
    [ 'title' => 'First World War', 'date' => '1914-07-28' ],
    [ 'title' => 'Second World War', 'date' => '1939-09-01' ],
    [ 'title' => 'First man on the moon', 'date' => '1969-07-20' ]
  ];

  return $newsList;
}

public function actionItemsList()
{
  $newsList = $this->dataItems();

  return $this->render('itemsList', ['newsList' => $newsList]);
}

After this, we will create a new function in NewsController, actionItemDetail, that is used to handle requests of detail of a news item. This function will expect a parameter, which will allow to filter the correct items from $newsList, for example, the title.

The following is the content of actionItemDetail:

public function actionItemDetail($title)
{
  $newsList = $this->dataItems();

  $item = null;
  foreach($newsList as $n)
  {
    if($title == $n['title']) $item = $n;
  }

  return $this->render('itemDetail', ['item' => $item]);
}

Next we have to create a new view file in views/news named itemDetail.php.

The following is the content of itemDetail.php located under views/news/:

<?php // $item is from actionItemDetail ?>

<h2>News Item Detail<h2>
<br />
Title: <b><?php echo $item['title'] ?></b>
<br />
Date: <b><?php echo $item['date'] ?></b>

If we point to http://hostname/basic/web/index.php?r=news/item-detail without passing the title parameter, we will see the following screenshot:

Example – create a controller to display the static news items list and details using the bootstrap template

It displays an error that tells us that the title parameter is missing.

Try to pass First%20%World%20War as the title parameter to the URL, like this http://hostname/basic/web/index.php?r=news/item-detail&title=First%20World%20War; the following will be the output:

Example – create a controller to display the static news items list and details using the bootstrap template

That is what we are expecting!

Finally, we want to connect together itemsList and itemDetail. In views/news/itemsList.php, we must change the title content into an anchor element, as follows:

<?php // $newsList is from actionItemsList ?>
<table>
  <tr>
    <th>Title</th>
    <th>Date</th>
  </tr>
  <?php foreach($newsList as $item) { ?>
  <tr>
    <th><a href="<?php echo Yii::$app->urlManager->createUrl(['news/item-detail' , 'title' => $item['title']]) ?>"><?php echo $item['title'] ?></a></th>
    <th><?php echo $item['date'] ?></th>
  </tr>
  <?php } ?>
</table>

To build a link, there is an available component, urlManager, which allows us to create links through the createUrl() method. The parameter in createUrl() is an array that contains the route path and variable to pass to the URL. To learn more about this method, just refer to the link http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html#createUrl%28%29-detail.

In our case, we have news/item-detail as the route to be called and the title parameter to be passed to the URL.

Note

The date can be formatted using the built-in formatter component. For example, to to display a date in the d/m/Y format, d/m/Y : Yii::$app->formatter->asDatetime($item['date'], "php:d/m/Y");.

It is advisable to use a unique identifier to pass data between routes. For this purpose, we add a third parameter, named id, to identify a record univocally.

The following is the content of NewsController:

public function dataItems()
{
  $newsList = [
    [ 'id' => 1, 'title' => 'First World War', 'date' => '1914-07-28' ],
    [ 'id' => 2, 'title' => 'Second World War', 'date' => '1939-09-01' ],
    [ 'id' => 3, 'title' => 'First man on the moon', 'date' => '1969-07-20' ]
  ];
  return $newsList;
}

public function actionItemsList()
{
  $newsList = $this->dataItems();
  return $this->render('itemsList', ['newsList' => $newsList]);
}
public function actionItemDetail($id)
{
  $newsList = $this->dataItems();

  $item = null;
  foreach($newsList as $n)
  {
    if($id == $n['id']) $item = $n;
  }

  return $this->render('itemDetail', ['item' => $item]);
}

Then, change the parameter in the createUrl parameter in views/news/itemsList.php:

<table>
  <tr>
    <th>Title</th>
     <th>Date</th>
  </tr>
  <?php foreach($newsList as $item) { ?>
  <tr>
    <th><a href="<?php echo Yii::$app->urlManager->createUrl(['news/item-detail' , 'id' => $item['id']]) ?>"><?php echo $item['title'] ?></a></th>
    <th><?php echo Yii::$app->formatter->asDatetime($item['date'], "php:d/m/Y"); ?></th>
  </tr>
  <?php } ?>
</table>
..................Content has been hidden....................

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