Yii

2012-07-25 12 views
6

में registerScript विधि से स्क्रिप्ट आदेश मजबूर मैं एक विजेट इस तरहYii

class MyWidget extends CWidget { 
    public function run(){ 
     Yii::app()->clientScript->registerScript(__CLASS__, <<<JAVASCRIPT 
var a = "Hello World!"; 
JAVASCRIPT 
     , CClientScript::POS_END); 
    } 
} 

नीचे और लेआउट में, मैं इस

<?php $this->widget('MyWidget');?> 
<?php echo $content;?> 

लेकिन एक में की तरह विजेट फोन अपने आप ही स्क्रिप्ट पंजीकृत करता है बनाया फ़ाइल देखें, मुझे उस विजेट द्वारा घोषित वैरिएबल की आवश्यकता है।

<?php 
Yii::app()->clientScript->registerScript('script', <<<JAVASCRIPT 
    alert(a); 
JAVASCRIPT 
    , CClientScript::POS_END); 
?> 

ध्यान दें कि दोनों registerScript विधि में मैं स्क्रिप्ट स्थिति के रूप में POS_END का उपयोग के बाद से मैं स्क्रिप्ट (CoreScript जैसे jQuery, jQueryUI आदि सहित) के सभी <body> टैग के बाद डाल करने के लिए करना चाहते हैं।

समस्या यह है कि प्रस्तुत स्क्रिप्ट दृश्य फ़ाइल से एक को दिखाएगी और उसके बाद विजेट से एक।

alert(a); 
var a = "Hello World!"; 

जैसा कि हम देख सकते हैं, उपर्युक्त कोड काम नहीं करेगा इसलिए मुझे दूसरी पंक्ति को ऊपर की रेखा से ऊपर रखना होगा।

आदेश को बल देने के तरीके पर कोई विचार? मैं CClientScript (और एक नया registerScript विधि बना रहा हूं) को विस्तारित करने के साथ ठीक हूं, जब तक कि सभी स्क्रिप्ट अंत स्थिति में प्रस्तुत की जाएंगी और मुझे उन इनलाइन जावास्क्रिप्ट कोड को नए पैकेज या फ़ाइल में खींचने की आवश्यकता नहीं है।

उत्तर

8

तो मैं अंत में यह करने के लिए एक हैक खोजने के सिर पर रजिस्टर का प्रयास करें। मैं एक नई ClientScript कक्षा का विस्तार करता हूं और registerScript विधि को संशोधित करता हूं, इसलिए यह एक और परम $level स्वीकार करेगा।

public function registerScript($id, $script, $position = self::POS_END, $level = 1); 

सोचो के बारे में $level सिर्फ सीएसएस में z-index, अधिक से अधिक $level की संख्या है, सिवाय इसके की तरह, कम स्क्रिप्ट की स्थिति हो जाएगा।

उदाहरण

Yii::app()->clientScript->registerScript('script1', '/** SCRIPT #1 **/', CClientScript::POS_END, 1); 
Yii::app()->clientScript->registerScript('script2', '/** SCRIPT #2 **/', CClientScript::POS_END, 2); 
Yii::app()->clientScript->registerScript('script3', '/** SCRIPT #3 **/', CClientScript::POS_END, 1); 

हालांकि script3script2 के बाद घोषित किया जाता है, प्रदान की गई स्क्रिप्ट में, यह script2 ऊपर दिखाई देगा के बाद से script2 की $level मूल्य script3 की तुलना में अधिक है के लिए

यहां मेरा समाधान कोड है। यह वही काम कर रहा है जो मैं चाहता हूं हालांकि मुझे यकीन नहीं है कि व्यवस्था विधि को अनुकूलित किया गया है या नहीं।

/** 
* ClientScript manages Javascript and CSS. 
*/ 
class ClientScript extends CClientScript { 
    public $scriptLevels = array(); 

    /** 
    * Registers a piece of javascript code. 
    * @param string $id ID that uniquely identifies this piece of JavaScript code 
    * @param string $script the javascript code 
    * @param integer $position the position of the JavaScript code. 
    * @param integer $level the rendering priority of the JavaScript code in a position. 
    * @return CClientScript the CClientScript object itself (to support method chaining, available since version 1.1.5). 
    */ 
    public function registerScript($id, $script, $position = self::POS_END, $level = 1) { 
     $this->scriptLevels[$id] = $level; 
     return parent::registerScript($id, $script, $position); 
    } 

    /** 
    * Renders the registered scripts. 
    * Overriding from CClientScript. 
    * @param string $output the existing output that needs to be inserted with script tags 
    */ 
    public function render(&$output) { 
     if (!$this->hasScripts) 
      return; 

     $this->renderCoreScripts(); 

     if (!empty($this->scriptMap)) 
      $this->remapScripts(); 

     $this->unifyScripts(); 

     //=================================== 
     //Arranging the priority 
     $this->rearrangeLevels(); 
     //=================================== 

     $this->renderHead($output); 
     if ($this->enableJavaScript) { 
      $this->renderBodyBegin($output); 
      $this->renderBodyEnd($output); 
     } 
    } 


    /** 
    * Rearrange the script levels. 
    */ 
    public function rearrangeLevels() { 
     $scriptLevels = $this->scriptLevels; 
     foreach ($this->scripts as $position => &$scripts) { 
      $newscripts = array(); 
      $tempscript = array(); 
      foreach ($scripts as $id => $script) { 
       $level = isset($scriptLevels[$id]) ? $scriptLevels[$id] : 1; 
       $tempscript[$level][$id] = $script; 
      } 
      foreach ($tempscript as $s) { 
       foreach ($s as $id => $script) { 
        $newscripts[$id] = $script; 
       } 
      } 
      $scripts = $newscripts; 
     } 
    } 
} 

तो मैं सिर्फ config

'components' => array(
    'clientScript' => array(
     'class' => 'ClientScript' 
) 
) 
1

Yii::app()->clientScript->registerScript(__CLASS__, <<<JAVASCRIPT 
var a = "Hello World!"; 
JAVASCRIPT 
, CClientScript::POS_HEAD); 
+0

मेरे इरादे अंत पर लिपियों के सभी प्रतिपादन किया गया है। बात यह है कि विजेट में लिपि jQuery पर निर्भर करती है, और मैंने 'कोरस्क्रिप्टपॉशन' फ़ील्ड (http://www.yiiframework.com/doc/api/1.1/CClientScript#coreScriptPosition- सेटिंग सेट करके अंत में सभी कोरकॉन डाल दिया है। विवरण) POS_END के रूप में। –

+0

खैर, यू के पास बुरा विचार है, या यू को विभिन्न घोषणाओं को विभाजित करना है, विगेट्स स्क्रिप्ट ओटी ईएनडी का शरीर, या यू को ईएनडी को पढ़ने के लिए बदलना है: वाईआई :: ऐप() -> क्लाइंटस्क्रिप्ट-> रजिस्टरस्क्रिप्ट ('स्क्रिप्ट' , <<< जावास्क्रिप अलर्ट (ए); जावास्क्रिप , सीसीलिएंटस्क्रिप्ट :: POS_READY); – Sergey

1

मैं Yii करने के लिए एक पैच योगदान दिया है आदेश अनुमति देने के लिए (आगे जोड़ते, जोड़ने संख्या)

में clientScript घटक के रूप में कक्षा लगाने की जरूरत है

आप इसे यहां देख सकते हैं https://github.com/yiisoft/yii/pull/2263

अगर इसे आपके स्थान पर नहीं मिला है, तो आप अपनी खुद की कक्षा में CClientScript को एपी में बढ़ा सकते हैं अपने परिवर्तनों को

लेकिन सामान्य ठीक से लिखा जे एस में स्वतंत्र कुछ वैश्विक गुंजाइश को परिभाषित करने वार्स आप (खिड़की के गुण के रूप में उन्हें प्रदान कर सकते हैं एक गैर मौजूदा संपत्ति तक पहुँचने के बजाय उदाहरण के लिए आदेश का काम करना चाहिए चलती हैं js में एक त्रुटि फेंक नहीं है)

0

CClienScript का विस्तार करने की कोई आवश्यकता नहीं है। इस समस्या का एक आसान समाधान आपके नियंत्रक में $ नियंत्रक में $ स्क्रिप्ट सरणी बनाना होगा और उस चर पर दृश्य स्क्रिप्ट जोड़ें। अपनी लेआउट फ़ाइल में आप उन लोगों को पंजीकृत करने के बाद अपनी $ स्क्रिप्ट्स सरणी में संग्रहीत स्क्रिप्ट पंजीकृत करेंगे जिन्हें आप पहले प्रस्तुत करना चाहते हैं। उदा .:

अपने नियंत्रक

public $scripts = []; 

अपने लेआउट में :

$baseURL = Yii::app()->request->baseUrl; 
$clientScript = Yii::app()->clientScript; 
$clientScript->registerScriptFile($baseURL . '/js/jquery.min.js', CClientScript::POS_END); 
$clientScript->registerScriptFile($baseURL . '/js/bootstrap.min.js', CClientScript::POS_END); 

और अपने ध्यान में रखते हुए

<?php array_push($this->scripts,"/js/summernote.min.js");?> 
+0

सबसे आसान और सर्वोत्तम प्रदर्शन। –

+0

नहीं, काम नहीं करता है – surfer190

0

सीसीलिएंटस्क्रिप्ट क्लास को @Petra के रूप में ओवरराइड करें, यहां पर कोड है जिसका उपयोग मैं कर रहा हूं, @ पेट्रा कोड का उपयोग करने के बाद और मेरे लिए काम नहीं किया।

class ClientScript extends CClientScript { 

public $scriptLevels; 

public function registerScript($id, $script, $position = null, $level = 1, array $htmlOptions = array()) { 
    $this->scriptLevels[$id] = $level; 
    return parent::registerScript($id, $script, $position, $htmlOptions); 
} 

public function render(&$output) { 
    foreach ($this->scripts as $key => $value) { 
     $this->scripts[$key] = $this->reorderScripts($value); 
    } 
    parent::render($output); 
} 

public function reorderScripts($element) { 
    $tempScripts = array(); 
    $buffer = array(); 
    foreach ($element as $key => $value) { 
     if (isset($this->scriptLevels[$key])) { 
      $tempScripts[$this->scriptLevels[$key]][$key] = $value; 
     } 
    } 
    ksort($tempScripts); 
    foreach ($tempScripts as $value) { 
     foreach ($value as $k => $v) { 
      $buffer[$k] = $v; 
     } 
    } 
    return $buffer; 
} 

} 

और फिर, अपनी कॉन्फ़िग फ़ाइल पर जाएँ, और में घटकों अनुभाग को संपादित करें:

'components' => array(
    . 
    . 
    'clientScript' => array(
     'class' => 'ClientScript' 
    ), 
)