получить следующую и предыдущую идентификационную запись в базе данных на Yii - PullRequest
0 голосов
/ 15 января 2012

Мне нужна следующая и предыдущая запись идентификатора в базе данных на платформе Yii, чтобы кнопки навигации были следующими и назад?

Ответы [ 6 ]

9 голосов
/ 22 июля 2015

Я добавил следующие функции в мою модель в Yii2:

public function getNext() {
    $next = $this->find()->where(['>', 'id', $this->id])->one();
    return $next;
}

public function getPrev() {
    $prev = $this->find()->where(['<', 'id', $this->id])->orderBy('id desc')->one();
    return $prev;
}
5 голосов
/ 16 января 2012

Я сделал функцию, чтобы получить те идентификаторы, которые вы ищете.Я предлагаю вам объявить это в модели:

public static function getNextOrPrevId($currentId, $nextOrPrev)
{
    $records=NULL;
    if($nextOrPrev == "prev")
       $order="id DESC";
    if($nextOrPrev == "next")
       $order="id ASC";

    $records=YourModel::model()->findAll(
       array('select'=>'id', 'order'=>$order)
       );

    foreach($records as $i=>$r)
       if($r->id == $currentId)
          return isset($records[$i+1]->id) ? $records[$i+1]->id : NULL;

    return NULL;
}

Таким образом, чтобы использовать его, все, что вам нужно сделать, это:

YourModel::getNextOrPrevId($id /*(current id)*/, "prev" /*(or "next")*/); 

Он вернет соответствующий идентификатор следующегоили предыдущая запись.

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

2 голосов
/ 15 января 2012

Создание приватной переменной, которая используется для передачи информации другим функциям.

В модели:

class Model1 .....
{
   ...
   private _prevId = null;
   private _nextId = null;
   ...

   public function afterFind()  //this function will be called after your every find call
   {
    //find/calculate/set $this->_prevId;
    //find/calculate/set $this->_nextId;
   }

   public function getPrevId() {
      return $this->prevId;
   }

   public function getNextId() {
      return $this->nextId;
   }

}

Проверьте код, сгенерированный в ссылке ViewDetal, и измените ссылки Prev / Net в файле _view, используя

$model(or $data)->prevId/nextId

в разделе массива ('id' => #).

1 голос
/ 22 декабря 2016

Моя реализация основана на SearchModel.

Контроллер:

public function actionView($id)
{
    // ... some code before

    // Get prev and next orders
    // Setup search model
    $searchModel = new OrderSearch();
    $orderSearch = \yii\helpers\Json::decode(Yii::$app->getRequest()->getCookies()->getValue('s-' . Yii::$app->user->identity->id));
    $params = [];
    if (!empty($orderSearch)){
        $params['OrderSearch'] = $orderSearch;
    }
    $dataProvider = $searchModel->search($params);
    $sort = $dataProvider->getSort();
    $sort->defaultOrder = ['created' => SORT_DESC];
    $dataProvider->setSort($sort);

    // Get page number by searching current ID key in models
    $pageNum = array_search($id, array_column($dataProvider->getModels(), 'id'));
    $count = $dataProvider->getCount();
    $dataProvider->pagination->pageSize = 1;

    $orderPrev = $orderNext = null;
    if ($pageNum > 0) {
        $dataProvider->pagination->setPage($pageNum - 1);
        $dataProvider->refresh();
        $orderPrev = $dataProvider->getModels()[0];
    }
    if ($pageNum < $count) {
        $dataProvider->pagination->setPage($pageNum + 1);
        $dataProvider->refresh();
        $orderNext = $dataProvider->getModels()[0];
    }
    // ... some code after
}

OrderSearch:

public function search($params)
{
    // Set cookie with search params
    Yii::$app->response->cookies->add(new \yii\web\Cookie([
        'name' => 's-' . Yii::$app->user->identity->id,
        'value' => \yii\helpers\Json::encode($params['OrderSearch']),
        'expire' => 2147483647,
    ]));

    // ... search model code here ...
}

PS: убедитесь, что вы можете использовать array_column длямассив объектов.Это хорошо работает в PHP 7+, но в более низких версиях вы должны извлечь id самостоятельно.Может быть, это хорошая идея использовать array_walk или array_filter в PHP 5.4 +

0 голосов
/ 08 сентября 2016

Предыдущие решения проблематичны, когда вы получаете первую или последнюю запись, и они делают несколько вызовов в базу данных. Вот мое рабочее решение, которое работает с одним запросом, обрабатывает конец таблицы и отключает кнопки в конце таблицы:

в модели:

public static function NextOrPrev($currentId)
{
    $records = <Table>::find()->orderBy('id DESC')->all();

    foreach ($records as $i => $record) {
        if ($record->id == $currentId) {
            $next = isset($records[$i - 1]->id)?$records[$i - 1]->id:null;
            $prev = isset($records[$i + 1]->id)?$records[$i + 1]->id:null;
            break;
        }
    }
    return ['next'=>$next, 'prev'=>$prev];
}

Внутри контроллера:

     public function actionView($id)
{
    $index = <modelName>::nextOrPrev($id);
    $nextID = $index['next'];
    $disableNext = ($nextID===null)?'disabled':null;
    $prevID = $index['prev'];
    $disablePrev = ($prevID===null)?'disabled':null;

    // usual detail-view model
    $model = $this->findModel($id);

    return $this->render('view', [
        'model' => $model, 
        'nextID'=>$nextID,
        'prevID'=>$prevID,
        'disableNext'=>$disableNext,
        'disablePrev'=>$disablePrev,
    ]);
}

В поле зрения:

<?= Html::a('Next', ['view', 'id' => $nextID], ['class' => 'btn btn-primary r-align btn-sm '.$disableNext]) ?>
<?= Html::a('Prev', ['view', 'id' => $prevID], ['class' => 'btn btn-primary r-align btn-sm '.$disablePrev]) ?>
0 голосов
/ 22 сентября 2015

Взять оригинальный ответ и адаптировать его для Yii2 с небольшой очисткой:

/**
 * [nextOrPrev description]
 * @source /7223531/poluchit-sleduyschuy-i-predyduschuy-identifikatsionnuy-zapis-v-baze-dannyh-na-yii
 * @param  integer $currentId [description]
 * @param  string  $nextOrPrev  [description]
 * @return integer         [description]
 */
public static function nextOrPrev($currentId, $nextOrPrev = 'next')
{
    $order   = ($nextOrPrev == 'next') ? 'id ASC' : 'id DESC';
    $records = \namespace\path\Model::find()->orderBy($order)->all();

    foreach ($records as $i => $r) {

       if ($r->id == $currentId) {
          return ($records[$i+1]->id ? $records[$i+1]->id : NULL);
       }

    }

    return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...