0 Пользователей и 1 Гость просматривают эту тему.
  • 35 Ответов
  • 3655 Просмотров
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Полуабсолютный ноль в php ( имею опыт только в C++ плюс простейшие програмки на php без классового понимания языка)
Уверен, что моя проблема в классовом понимании php, но ответа найти не могу.
Пробую писать компонент, Прочитал курс г-на Рекуна Helloworld его и банально пытаюсь модифицировать под свои нужды
в default view который отображает записи таблицы вставил кнопку, по которой хочу отобразить другую таблицу с теми же id что и в основной таблице
Соответственно в контроллере имею этот id который выбрал пользователь и нажал на кнопку которую обрабатывает конроллер
Спойлер
[свернуть]

В модели вроде бы все как бы даже работает
и id сохраняется в функции saveitem() в переменную $currentId, обьявленную в классе, но почемуто  переменная в которой сохраняю функцию, недоступна в другой фунции - getListQuery, вернее равна null
Я понимаю что я где-то морожу глупость, но уверен виной - мое знание phpб ну либо глобальное непонимание MVC (наплодил объектов)
не дайте умереть дураком
Спойлер
[свернуть]
подскажите, что я делаю не так ?
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
А с чего вы взяли что метод getListQuery вызывается после вашего saveItem() и на том же объекте? Он вызывается в методе getItems() вообще-то, вы же от jmodelList наследуетесь. Получить переменную можно в самом методе из запроса или через состояние модели перед вызовом getItems на том же объекте .
« Последнее редактирование: 16.09.2015, 20:35:28 от zomby6888 »
интернет-блог: http://websiteprog.ru
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Спасибо за ответ
Я в Eclipseе ставлю брэйкпоинты, сначала выполняется saveItem()
кто вызывает getListQuery, я честно не очень понимаю, но он идет после saveItem()
если я правильно объявил и работаю с  $currentId ? то у меня подозрение что существует 2 объекта JmodelList  в одном из которых
эта переменная не сохранена, такое может быть?
я в принципе нашел вариант       
               $app = JFactory::getApplication();
      $currentId = $app->getUserState('selectedId');
а в контроллере соответственно setUserState .. вы  о нем говорите ? это через состояние модели ?
но всетаки хотелось понять почему через устанавливаемую в классе переменную не работает.

*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
подскажите, что я делаю не так ?
Все делаете не так! Банально не понимаете последовательности работы приложения увы!
У вас после
model->saveItem($pks[0]); // взять только один и сохранить его в модели
идет:
 $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
Тоесть перенаправление на новую страницу!
У вас текущее приложение уходит в небытие и идет переход на страницу  index.php?option=com_rentflat&view=events в вид  events  компонента com_rentflat
В котором этот вид и запрашивает getListQuery
Вы идете не по тому пути немножко!
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Из контроллера передать состояние в модель геморно, потому что надо переопределить метод display().  Это я считаю недоработкой фреймворка. Проще всего передать переменную в модель перед вызовом getItems() в прослойке вида (RentFlatViewEvents класс возможно в вашем случае):
Код: php
...
$model = $this->getModel();
$model->setState('currentId', 1);
$this->items = $this->get('Items');
...
Затем в getListQuery модели получить его:
Код: php
...
$currentId = $this->getState('currentId');
...

Еще проще взять из запроса. RentFlatControllerEvents наследуется от JСontrollerForm и вообще по идее не должен работать с моделью списка, тем более у вас там вообще редирект как уже вам написали.
интернет-блог: http://websiteprog.ru
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
если я правильно объявил и работаю с  $currentId ?
почему через устанавливаемую в классе переменную не работает.
$this->currentId. Пример:
Спойлер
[свернуть]
Не будь паразитом, сделай что-нибудь самостоятельно!
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Все делаете не так! Банально не понимаете последовательности работы приложения увы!
У вас после
model->saveItem($pks[0]); // взять только один и сохранить его в модели
идет:
 $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
Тоесть перенаправление на новую страницу!
У вас текущее приложение уходит в небытие и идет переход на страницу  index.php?option=com_rentflat&view=events в вид  events  компонента com_rentflat
В котором этот вид и запрашивает getListQuery
Вы идете не по тому пути немножко!
собственно я так и планировал, открыть экран, в заголовке гдето id первой таблице, с ее именем, и список подчиненных рекордов events с которыми буду выполнять какието действия. Единственное, чего не учитываю, наверное вы правы, как вернуться обратно к первой таблице. я думал возврат будет через меню.
подскажите как грамотно это сделать с тем чтобы вернуться к текущему приложению?
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
$this->currentId. Пример:
Спойлер
[свернуть]
пробовал и с this->. поведение такое же
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Из контроллера передать состояние в модель геморно, потому что надо переопределить метод display().  Это я считаю недоработкой фреймворка. Проще всего передать переменную в модель перед вызовом getItems() в прослойке вида (RentFlatViewEvents класс возможно в вашем случае):
Код: php
...
$model = $this->getModel();
$model->setState('currentId', 1);
$this->items = $this->get('Items');
...
Затем в getListQuery модели получить его:
Код: php
...
$currentId = $this->getState('currentId');
...

Еще проще взять из запроса. RentFlatControllerEvents наследуется от JСontrollerForm и вообще по идее не должен работать с моделью списка, тем более у вас там вообще редирект как уже вам написали.
спасибо, только у меня нет понимания как в этом  view получить id  выбранного рекорда, тот что у Вас равен единице, а в конроллере я просто раскопал, как он извлекается
я об этом -$pks = $input->post->get('cid', array(), 'array');
извините за тупость, но реально крыша  дымиться, первое время я просто хотел все бросить в виду полного непонимания ... да и сейчас вижу недалеко продвинулся.
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Мой предыдущий пост не имеет прямого отношения к вашей задаче, я только хотел указать на ваше неправильное оперирование свойствами класса.
По вашей задаче zomby6888 уже написал в своем последнем посте. Перед перенаправлением сохраните $currentId в сессии или передавайте ее в $_REQUEST.
P.S.
Код: php-brief
$pks = $input->post->get('cid', array(), 'array');
$model = $this->getModel();
$model->setState('currentId', $pks[0]);
$this->items = $this->get('Items');
Не будь паразитом, сделай что-нибудь самостоятельно!
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Спасибо всем большое.
я возможно или мне кажется начинаю понимать свою ошибку
Подтвердите пожалуйста что я правильно понимаю, или не понимаю ничего
Контроллер должен как то запустить view моей вторичной таблицы передав туда id (вопрос как )
view совершенно естественным образом ( тоесть без моего участия, внутри кода самой Joomla ) должен поднять модель events и (породить его из класса) и вызвать метод  getListQuery в модели, которая создается во view.
я же кодом  в контролере
$model = $this->getModel()
создаю обьект и сохраняя в нем id в в конечном счете получаю два обьекта, этот, и тот который порождается во view соответственно имею то что имею, в одном объекте id сохранен, в другом нет.

Если я думаю хоть немного  в правильном направлении(не уверен)  , то подскажите пожалуйста - как грамотно передавать выбранный пользователем id во view ? а оттуда в модель
с помощью тогоже $model->setState('currentId', $pks[0]);?
И надо ли его вообще передавать во view, поскольку он используется в выборке базы данных? Ну если только показать id родительского рекорда
и если я правильно думаю то в контроллере к модели его передавать нельзя поскольку $model = $this->getModel() породит ненужный объект?
Понимаю, сумбурно написал, но если есть  возможность ткнуть где я ошибаюсь, прокоментируйте мой опус.Спасибо
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Попробую внести ясность. Контороллер, модель и представление (на самом деле нифига не представление но я не буду усложнять, буду называть его просто view в дальнейшем) это все классы которые составляют MVC модель Joomla. Если в запросе не прописан какой то специфический контроллер то приложение создает экземпляр/объект контроллера по умолчанию и если в запросе не указана никакая другая задача то вызывается метод display() этого контроллера.

Что дальше контроллер разруливает в этом методе:

В этом методе контроллер создает (без вашего участия, если кончено вы его не перезагрузили/переопределили) экземпляр модели и экземпляр view (имя модели и view берется на основе наименования класса контроллера если вы их явно не указали в запросе или конструкторе). Затем он устанавливает экземпляр модели в определенное свойство полученного объекта view, чтобы методы view имели доступ к этому объекту модели. Затем контролер вызывает метод display() экземпляра view (не путать с методом display контроллера который я сейчас описываю). И вот там уже, в большинстве случаев и вызывается метод getItems() модели который в свою очередь вызывает метод  getListQuery для получения данных списка. Ну и там уже рендерится шаблон в который передаются данные списка.

Поэтому чтобы передать переменную в модель вы должны в этом методе получить экземпляр этой модели. Собственно это и делает метод getModel, возвращает модель которую контроллер установил для этого view в своем методе display. На сам деле там вроде даже массив этих моделей хранится но уж не буду усложнять.

Ну и вы на самом деле можете переопределить метод display, и установить переменную для модели в нем непосредственно. Это будет даже правильнее с точки зрения стандартов MVC, потому что по идее получать переменные из запроса должен контроллер в таких моделях. Но это не совсем удобно, чуть больше писанины будет надо каждый раз копировать содержимое метода.

P.S Это вот так вот вкратце, поправьте меня если где ошибся, за подробностями конечно надо лезть в литературу или исходники
интернет-блог: http://websiteprog.ru
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
« Последнее редактирование: 17.09.2015, 23:05:51 от robert »
Не будь паразитом, сделай что-нибудь самостоятельно!
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
только что проверил,  $this->get('Items') не создает новый экземпляр а возвращает тот что уже контроллер установил для view в свойстве $this->_defaultModel, и вызывает на нем соответствующий метод

Вобще там берется модель из свойства $this->_defaultModel. Там еще кстатии есть массив моделей в который можно другие модели устанавливать и если передать вторым парметром имя модели $this->get('Items', 'modelname')   то будет вызван метод getItems на экземпляре модели из этого массива
« Последнее редактирование: 17.09.2015, 22:27:13 от zomby6888 »
интернет-блог: http://websiteprog.ru
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Хм, тогда почему до сих пор ТС не может решить свою задачу? Или он просто хочет пообщаться?
« Последнее редактирование: 17.09.2015, 22:35:08 от robert »
Не будь паразитом, сделай что-нибудь самостоятельно!
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Видимо пытается понять как работает MVC  ^-^
интернет-блог: http://websiteprog.ru
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Проверил в своем компоненте: в аналогичной ситуации $this->get('Items') выдает null.
Не будь паразитом, сделай что-нибудь самостоятельно!
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Ну у меня разве что установлен $this->defaut_view для контроллера по умолчанию. Да ксатии, точняк я сейчас вспомнил что нужно установить это свойство контроллеру, иначе иначе он не установит модель по умолчанию для вьюхи. Тоже кстатии косяк фреймворка, он мог бы и на основе запроса устанавливать модель по умолчанию для view. Тоесть у меня в контролере прописано: protected $default_view = 'categories'; ( view='categories' у меня)

А хотя нет там косяка я сейчас внимательнее посмотрел, просто если view не указан в запросе его необходимо установить как свойство для контроллера по умолчанию



« Последнее редактирование: 17.09.2015, 23:16:59 от zomby6888 »
интернет-блог: http://websiteprog.ru
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Был не прав: в контроллере в методе $view->setModel() поставил второй аргумент=true и $this->get('Items') заработал.
Не будь паразитом, сделай что-нибудь самостоятельно!
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Ну да этот параметр он как раз и устанавливает экземпляр модели как модель по умолчанию для view
интернет-блог: http://websiteprog.ru
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Кстатии код в этой статье код:
Код: php
class blogController extends JController
{
    function display( $cachable = true )
    {
        $this->default_view = 'category';
        parent::display( $cachable );
    }
}
Можно заменить на:
Код: php
class blogController extends JController
{
    protected $default_view = 'category';
}

Правда они могут потом конструктор переписать, и присвоить туда что нибудь, даже если свойство определено
« Последнее редактирование: 18.09.2015, 00:07:22 от zomby6888 »
интернет-блог: http://websiteprog.ru
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Рад что мой глупый пост стал предметом обсуждения, деталей и ньюансов которого я все равно глубоко не понял
Тем не менее у себя в коде я вижу что ни черта у меня не работает так как я бы хотел
c подачи zomby6888
в контроллере Events добавил  $this->items = $this->get('Items');
в результате он возвращает null
Спойлер
[свернуть]
конкретно в кишочках Joomla в файле object.php идет сразу возврат
public function get($property, $default = null)
   {
      if (isset($this->$property))
      {
         return $this->$property;
      }

      return $default;
   }

а в модели

Спойлер
[свернуть]
в трассировке в Eclipseе вижу  конструтор __construct($config = array())
вызывается два раза, первый до функции showevents в контроллере
а второй, когда фунция уже выполнилась
getListQuery() не вызывается, если закоментирована во view
Спойлер
[свернуть]
и вызывается если она там есть, но в ней $currentId=-1
 мне кажется у меня два объекта model
в конце концов бог с ним с моим кодом, если он нарушает концепции MVC
подскажите как правильно решать мою задачу
имеется view list какой то таблицы записей
я хочу по custom кнопке ( это контроллер, как я понял без вариантов) и отмеченном рекорде этой таблицы
иметь выборку записей(модель и view)  другой таблицы в котором будут только рекорды у которых какое то поле будет равным id отмеченного рекорда $query->where($db->quoteName('Flat_id'). ' LIKE '. '$currentId');

как такое решать  грамотно, что бы не иметь геморроя с передачей id в модель?


Или это неправильно, по кнопке получать view list рекордов ?

*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Неправильно.
В controller
Спойлер
[свернуть]
В view
Спойлер
[свернуть]
В model
Спойлер
[свернуть]

P.S. showevents() в контроллере - лишняя, уже существует функция по-умолчанию JControllerLegacy->display().
« Последнее редактирование: 18.09.2015, 16:24:38 от robert »
Не будь паразитом, сделай что-нибудь самостоятельно!
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
robert а зачем это извращение:
Код: php
class RentFlatControllerEvents extends JControllerForm
{
 
public function showevents()
   {
      // Redirect to the list screen.
      $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
   }
 
}
это же масло масляное, зачем делать задачу на переход в стандартный таск display()?!
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Ну, я просто взял код ТС, думая, что так будет легче объяснять. Потом уже дописал
P.S. showevents() в контроллере - лишняя, уже существует функция по-умолчанию JControllerLegacy->display().
Не будь паразитом, сделай что-нибудь самостоятельно!
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
public function showevents(){
    // Get the input
   $input = JFactory::getApplication()->input;
   $pks = $input->post->get('cid', array(), 'array'); // взять array выбранных пользователем id
   
   // Sanitize the input
   JArrayHelper::toInteger($pks);
   // Get the model
   $model = $this->getModel();
   $model->setState('currentId', $pks[0]);
        $this->items = $this->get('Items');   /// null
   // Redirect to the list screen.
   $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
}
Ещё раз по этому коду (кстати у вас нет банального понимания как работает PHP)!
Объясню на пальцах!
вы выполняете код в методе showevents() и он выполняется, но когда доходит до строки $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
у вас идет перенаправление в index.php?option=com_rentflat&view=events!
То есть то что вы делали все это время, ИСЧЕЗАЕТ! открывается новый экземпляр сайта! Все равно что вы закроете текущий сайт и откроете страницу index.php?option=com_rentflat&view=events!
У вас все передалось и в модель и в контроллер, но на текущей странице! Но как только доходит до строки $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false)), у вас открывается другая страница, идет новая инициалициализация сайта, запуск компонента com_rentflat и вывод вида events, ваш метод showevents уже не работает, и уже установленных переменных нету!
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
Лично мне больше нравится такой способ:
Модель:
Спойлер
[свернуть]
Вид:
Спойлер
[свернуть]
*

tm2010

  • Захожу иногда
  • 76
  • 0 / 0
Ещё раз по этому коду (кстати у вас нет банального понимания как работает PHP)!
Объясню на пальцах!
вы выполняете код в методе showevents() и он выполняется, но когда доходит до строки $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false));
у вас идет перенаправление в index.php?option=com_rentflat&view=events!
То есть то что вы делали все это время, ИСЧЕЗАЕТ! открывается новый экземпляр сайта! Все равно что вы закроете текущий сайт и откроете страницу index.php?option=com_rentflat&view=events!
У вас все передалось и в модель и в контроллер, но на текущей странице! Но как только доходит до строки $this->setRedirect(JRoute::_('index.php?option=com_rentflat&view=events', false)), у вас открывается другая страница, идет новая инициалициализация сайта, запуск компонента com_rentflat и вывод вида events, ваш метод showevents уже не работает, и уже установленных переменных нету!
Замечательно, это не секрет что я в php слабее крысы
код спер из какогото компонента, который по кнопке загружает файл, видимо там оправдано, потомучто  моменту редиректа, задание выполнено
но если я убираю редирект, то я вижу голую страницу с URL http://localhost/administrator/index.php?option=com_rentflat&view=rentflats и никакого view=events
вы подскажите как правильно  решить мою задачу
что туда поставить ? если я его убираю
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Прописать условие для сохранения данных в БД

Автор semen1707

Ответов: 0
Просмотров: 314
Последний ответ 14.04.2021, 00:59:44
от semen1707
Создание компонента для табеля рабочего времени

Автор sashahz

Ответов: 7
Просмотров: 476
Последний ответ 12.04.2021, 11:12:11
от sashahz
Вызов формы компонента в pop-up, при клике по ссылке из любого места

Автор SkyAn

Ответов: 1
Просмотров: 394
Последний ответ 01.03.2021, 04:08:48
от gartes
Документация по разработки компонента для Joomla 3.x

Автор Aspik

Ответов: 9
Просмотров: 2900
Последний ответ 23.01.2021, 07:55:56
от hmr
Сборка инсталятора компонента файлами из разных папок с привлечением github

Автор borro

Ответов: 1
Просмотров: 414
Последний ответ 25.12.2020, 21:21:30
от platonische