अद्यतन ajax के माध्यम से

हेलो, हेब्रोसोसिटी!

इस सूत्र में, मैं Yii में CGridView घटक के सबसे उपयुक्त उपयोग पर चर्चा करना चाहता हूं।
नीचे मैं 3 तरीके बताऊंगा जो मैं व्यक्तिगत रूप से देखता हूं, और मुझे आपके विचारों को टिप्पणियों में सुनकर खुशी होगी।



तो, कार्य :
कई ब्लॉकों वाले पृष्ठ की आवश्यकता होती है, जिनमें से एक में एक टेबल (ग्रिड) होना चाहिए।
अजाक्स के माध्यम से ग्रिड को सॉर्ट और पैगेट करने की क्षमता की आवश्यकता है।

आसान लगता है, है ना? आइए देखें कि Yii हमें क्या प्रदान करता है।

विधि 1: मानक CRUD पीढ़ी


उत्पन्न कोड में नियंत्रक में 1 कार्रवाई और 1 दृश्य होता है:
नियंत्रक:
public function actionAdmin() { $model=new Product('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['Product'])) $model->attributes=$_GET['Product']; $this->render('index',array( 'model'=>$model, )); } 

index.php :
 ... <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'product-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, ... 


सामान्य तौर पर, सब कुछ काम करता है, लेकिन हर बार जब आप ग्रिड में अजाक्स सॉर्टिंग या नेविगेशन का उपयोग करते हैं, तो सर्वर पृष्ठ का पूर्ण HTML-कोड लौटाता है! जिसमें से ग्रिड को अपडेट करने के लिए केवल एक छोटा HTML-टुकड़ा प्रयोग किया जाता है। यदि पृष्ठ में कई तत्व हैं (उदाहरण के लिए, एक और ग्रिड), तो सर्वर साइड पर सभी व्यर्थ में संसाधित होते हैं। मेरी राय में सबसे अच्छा समाधान नहीं है।

विधि 2. अजाक्स के माध्यम से सभी


विधि 1 की समस्या को हल करने के लिए, ग्रिड बनाने के लिए एक अलग कार्रवाई और दृश्य बनाएं। वे केवल अजाक्स के माध्यम से काम करेंगे और रेंडरपार्टियल () विधि के माध्यम से सामग्री लौटाएंगे, जो ग्रिड के लिए केवल आवश्यक HTML छोड़ देगा:
नियंत्रक:
  public function actionGrid() { if(!Yii::app()->request->isAjaxRequest) throw new CHttpException('Url should be requested via ajax only'); $model=new Product('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['Product'])) $model->attributes=$_GET['Product']; $this->renderPartial('_grid',array( 'model'=>$model, )); } 

_grid.php में केवल विजेट कोड होता है:
 ... <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'product-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, ... 

और index.php पेज लोड होने पर पहली बार ग्रिड को ऊपर खींचता है:
  <div id="grid-container"></div> yii::app()->clientScript->registerScript('load-grid', ' $("#grid-container").load("product/grid"); '); 


यह साफ दिखता है, लेकिन काम नहीं करता है :) रेंडरपार्टियल () विधि आवश्यक जेएस और सीएसएस फाइलें वापस नहीं करता है! केवल एच.टी.एम.एल.
लेकिन रुकिए! RenderPartial () में "प्रक्रिया आउटपुट" नामक एक अतिरिक्त पैरामीटर है, जो js और css को वापस करने की अनुमति देता है।
नियंत्रक में बदलें:
  public function actionGrid() { if(!Yii::app()->request->isAjaxRequest) throw new CHttpException('Url should be requested via ajax only'); $model=new Product('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['Product'])) $model->attributes=$_GET['Product']; $this->renderPartial('_grid',array( 'model'=>$model, ), false, true); } 

हम पृष्ठ को लोड करते हैं और फिर से बायक देखते हैं: jquery.js और अन्य स्क्रिप्ट्स हर बार लोड करने के लिए शुरू होती हैं जब हम ajax के माध्यम से ग्रिड को अपडेट करते हैं!
बेशक, उन्हें एक बार लोड किया जाना चाहिए, लेकिन रेंडरपार्टियल () सही ढंग से प्रत्येक अनुरोध पर उन्हें वापस कर देता है।
पुन: लोडिंग स्क्रिप्ट को अक्षम कैसे करें? ऐसा करने के लिए, आप एक अलग एक्सटेंशन लगा सकते हैं, जो, जब अजाक्स-अनुरोध करता है, तो पहले से ही पृष्ठ पर लोड की गई स्क्रिप्ट को काट देता है।
वोइला, सब कुछ काम करता है! लेकिन व्यक्तिगत रूप से, मुझे उम्मीद है कि Yii इस समस्या को बिना किसी एक्सटेंशन के मानक तरीकों से हल करेगा ...

विधि 3. पहली बार को छोड़कर, अजाक्स के माध्यम से सब कुछ


लेकिन क्या होगा अगर आप पहली बार नियमित अनुरोध के साथ ग्रिड को लोड करते हैं, और फिर अजाक्स के माध्यम से अपडेट करते हैं?
नियंत्रक में, सब कुछ लगभग अपरिवर्तित रहता है, बस अतिरिक्त मापदंडों के बिना रेंडरपार्टियल में isAjaxRequest चेक को हटा दें:
  public function actionGrid() { if(!Yii::app()->request->isAjaxRequest) throw new CHttpException('Url should be requested via ajax only'); $model=new Product('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['Product'])) $model->attributes=$_GET['Product']; $this->renderPartial('_grid',array( 'model'=>$model, )); } 

मुख्य दृश्य index.php में, हम सीधे एक्शनग्रिड कहते हैं ():
  <div id="grid-container"><?php $this->actionGrid(); ?></div> 

और _grid.php में हम भविष्य के ग्रिड अपडेट के लिए ajaxUrl पैरामीटर सेट करते हैं। अन्यथा, अजाक्सुएल वर्तमान url (उदा। उत्पाद / सूचकांक) से लेगा:
  $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'product-grid', 'dataProvider'=>$model->search() , 'filter'=>$model, 'ajaxUrl' => array('product/grid'), ... 

हम परिणाम को देखते हैं: शुरू में ग्रिड सही ढंग से लोड होता है, लेकिन नेविगेशन काम नहीं करता है!
पृष्ठ लिंक उत्पाद / ग्रिड के बजाय उत्पाद / सूचकांक को इंगित करना जारी रखते हैं। Yii कोड का अध्ययन करने से पता चला कि पेजिनेशन में लिंक किसी भी तरह से ajaxUrl पैरामीटर से जुड़े नहीं हैं और वर्तमान अनुरोध से लिए गए हैं । पहले बूट में कौन सा समान नहीं है, क्योंकि हम एक क्रिया से दूसरे का आह्वान करते हैं। मेरी राय में, ऐसी चुनौती वैचारिक रूप से भी पूरी तरह सही नहीं है।
लेकिन कहीं जाने के लिए, हम इसे डेटा प्रदाता के पृष्ठांकन ऑब्जेक्ट में मार्ग पैरामीटर सेट करके ठीक करते हैं:
_grid.php :
 <?php $dataProvider = $model->search(); $dataProvider->pagination->route = 'product/grid'; $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'product-grid', 'dataProvider'=>$dataProvider , 'filter'=>$model, 'ajaxUrl' => array($dataProvider->pagination->route), ... 

अब लगभग सब कुछ वैसा ही है जैसा कि होना चाहिए। ग्रिड लोड हो रहा है, छँटाई और नेविगेशन काम कर रहा है।
लेकिन मरहम में एक मक्खी थी:
यदि ग्रिड किसी तरह से सॉर्ट किया गया है और पहले पृष्ठ पर नहीं है, और हम इसके अपडेट को js के माध्यम से कहते हैं:
 $("#product-grid").yiiGridView("update"); 

तब यह मानक छँटाई के साथ पहले पृष्ठ पर रीसेट हो जाता है। यह शर्म की बात है, है ना? ऐसा इसलिए है क्योंकि ajaxUrl स्पष्ट रूप से निर्दिष्ट है और अद्यतन हमेशा उस पर एक अनुरोध भेजता है। लेकिन अगर आप ajaxUrl को निर्दिष्ट नहीं करते हैं, तो ग्रिड को अपडेट करने पर वर्तमान पृष्ठ और सॉर्ट बचाता है ! क्योंकि url जिसके द्वारा इसे प्राप्त किया गया था, ग्रिड के अंदर संग्रहीत किया जाता है (विशेषकर कुंजी के साथ div के शीर्षक विशेषता में)। लेकिन यह भी असंभव नहीं है कि अजाक्सुएल निर्दिष्ट न करें, क्योंकि तब अनुरोध स्रोत ग्रिड url पर जाएंगे, अर्थात उत्पाद / सूचकांक।

मेरे पास एकमात्र समाधान पहले (गैर-अजाक्स) ग्रिड गठन में एक ही शीर्षक को बदलना था। और ajaxUrl को बिल्कुल भी निर्दिष्ट न करें।
परिणामी _grid.php इस तरह दिखता है:
 <?php $dataProvider = $model->search(); $dataProvider->pagination->route = 'product/grid'; $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'product-grid', 'dataProvider'=>$dataProvider , 'filter'=>$model, // 'ajaxUrl' => array($dataProvider->pagination->route), ... if(!yii::app()->request->isAjaxRequest) { yii::app()->clientScript->registerScript('grid-first-load', ' $("#product-grid").children(".keys").attr("title", "'.$this->createUrl($dataProvider->pagination->route).'"); '); } 


अब सब कुछ उसी तरह काम करता है जैसा उसे करना चाहिए! केवल उपरोक्त बैसाखी की उपस्थिति से शर्मिंदा।

निष्कर्ष


मैं आपके विचारों / टिप्पणियों को ऊपर के तरीकों पर और आपकी yii- परियोजनाओं में ग्रिड के उपयोग पर सुनना चाहूंगा।
आपका ध्यान के लिए धन्यवाद!

Source: https://habr.com/ru/post/In140109/


All Articles