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) показать список позиций портфеля для индекса eg /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] 

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

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

благодаря

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

 function index() { $this->set('posts', $this->Portfolio->find('all')); // Make sure the model Portfolio is accessible from here, ie 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 доступна beforeFilter в вашем приложении.

/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 .

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

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

Пожалуйста, прочитайте документы .

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

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

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

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

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

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

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

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

 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) 

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

Я внесла некоторые изменения в вашу функцию 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' ); ?> 

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

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

 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); } } 

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

контроллер:

 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 />"; } 

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

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

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

 //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')); ?>