CakePHP передает данные элементу

В моем контроллере есть следующий код:

function index()
{
    $posts = $this->set('posts', $this->Portfolio->find('all'));

    if (isset($this->params['requested']))
    {
        return $posts;
    }
    else
    {
        $this->set('posts', $this->Portfolio->find('all'));
    }
}

и то, что я хочу сделать, это a) показать список позиций портфеля для индекса, например. /portfolio/ и b) отобразить список элементов портфеля внутри элемента, чтобы пользователь мог получить доступ к элементам портфеля из моей боковой панели по всему сайту.

Вот мой элемент для боковой панели:

<?php $posts = $this->requestAction('portfolio/index'); ?>
<ul>
    <?php foreach ($posts as $post): ?>
    <li><?php echo $this->Html->link($post['Portfolio']['title'], array('action' => 'view', $post['Portfolio']['id']));?></li>
    <?php endforeach; ?>
</ul>

а затем я называю это так в моем макете:

<?php $this->element('portfolio-nav', array('posts' => $posts) ); ?>

Однако он дает следующую ошибку:

Notice (8): Undefined variable: posts [APP/controllers/portfolio_controller.php, line 16]

И не отображает список элементов на боковой панели.

Я почти уверен, что я написал в своем контроллере мусор, поэтому, если кто-нибудь может помочь мне заставить его работать, это будет потрясающе.

Спасибо

Ответ 1

Я ответил на тот же вопрос вчера. Почему ваш контроллер настолько сложный? Думаю, вам не нужно ничего больше, чем

function index() {
    $this->set('posts', $this->Portfolio->find('all'));
    // Make sure the model Portfolio is accessible from here, i.e. place this
    // action in PortfoliosController or load it using 
    // ClassRegistry::init('Portfolio')->find... 
}

Затем в вашем представлении index.ctp:

<?php echo $this->element('foobar', array('posts' => $posts)); ?>

Если вы хотите иметь возможность запрашивать это со всех страниц вашего сайта (боковая панель или что-то еще), вы можете использовать requestAction или поместить $this->set... в свой AppController. Если вы используете requestAction в своем элементе, вам не нужно передавать array('posts' => ...) в свой вызов $this->element.


Хорошо, ясно, что вам нужно гораздо больше направлений. Позвольте мне объяснить это шаг за шагом. Сначала нам нужно создать beforeFilter на вашем AppController, поэтому переменная $posts доступна извне в вашем приложении.

/app/app_controller.php:

<?php
class AppController extends Controller {
    function beforeFilter() {
        parent::beforeFilter();
        $this->set('posts', ClassRegistry::init('Portfolio')->find('all'));
    }
}

Затем мы создаем простой элемент в app/views/elements/foobar.ctp:

<?php debug($items); ?>

Наконец, мы вызываем элемент откуда-то в представлении:

<?php echo $this->element('foobar', array('items' => $posts)); ?>

Мы назначаем переменную $posts (которую мы определили в вашем AppController) ключ items, потому что наш элемент ожидает переменную $items.

Ответ 2

Второй аргумент метода element передает данные. Что вам нужно:

$this->element('portfolio-nav', array('posts' => $posts) );

Прочтите docs.

Ответ 3

Одна вещь, о которой я не думаю, была поднята, ваше сообщение об ошибке:

Notice (8): Undefined variable: posts [APP/controllers/portfolio_controller.php, line 16]

находится в контроллере. То, что вы разместили, выглядит хорошо (хотя и немного подробный код), поэтому я бы спросил, где строка 16 в PortfolioController и почему $posts не определен?

Возврат значения из контроллера для использования в элементе работает вообще, поэтому проблем нет.

Ответ 4

Элемент с параметром

$this->element('elementname', array('var_name'=>$var));

Ответ 5

вы устанавливаете $posts var в элементе и пытаетесь передать его из макета элементу o.o

ваш код будет в этом порядке

render layout
include element passing variable
set var with requestAction

Еогеасп

вы должны делать

render layout
include element (dont pass anything)
set var with requesAction (you get the data here so why are you trying to pass it in)

Ответ 6

Попробуйте это и сообщите мне, работает ли это или нет.

Я внес некоторые изменения в вашу функцию Controller:: index():

function index () {
    // this is the problem
    // $posts = $this->set('posts', $this->Portfolio->find('all'));

    $posts = $this->Portfolio->find ( 'all' );

    if (isset($this->params['requested']))
    {
        return $posts;
    }
    else
    {
        // you already have the posts
        //$this->set('posts', $this->Portfolio->find('all'));

        $this->set ( 'posts', $posts );
    }
}

никаких изменений в элементе portfolio-nav..

измените вызов в своем макете, чтобы он стал:

<?php $this->element ( 'portfolio-nav' ); ?>

Надеюсь, это было полезно для вас. удачи с вашим развитием.

Ответ 7

Вы также можете сделать это.

class AppController extends Controller {

    public $var;    

    public function beforeFilter()
    {
         $this->var = ClassRegistry::init('Portfolio')->find('all');
    }
 }
class YourController extends AppController {

    public function index() {

        debug($this->var);
    }
}

Ответ 8

Вот так я решил это очень просто:

контроллер:

function birdsTwo() { 
    return $this->Bird->find('all', array('order' => 'Bird.name ASC', 'limit' => 2));   
}

раскладка:

<?php echo $this->element('quick_5_birds'); ?>

элемент:

$birds = $this->requestAction('/birds/birdsTwo/');
    foreach($birds as $bird) {
          echo $this->Html->link(__($bird['Bird']['name'], true), 
array('controller' =>'bird','action' => 'view', $bird['Bird']['id'])) . "<br />";
}

Ответ 9

Просмотр документации CakePHP http://book.cakephp.org/2.0/en/views.html

echo $this->element('helpbox', array(
    "helptext" => "Oh, this text is very helpful."
));

Если вам нужна переменная в каждом представлении, вы должны установить ее в сеансе.

Ответ 10

//Controller users
public function getUsers(){

     $users=  $this->User->find("all");

     return $users;
    }


//Element name users

$this->requestAction(array('controller'=>'users','action'=>'getUsers'))

//vista name view
 print_r( $this->element('users')); ?>