从子视图将Javascript文件附加到InlineScript集合的末尾

时间:2013-02-08 12:17:00

标签: zend-framework2

我正在使用Zend Framework 2.

在我的布局文件中,我会注入一些像这样的javascript文件:

$this->InlineScript()
            ->appendFile($this->basePath() . '/js/myfile.js');


echo $this->InlineScript();

现在我想从视图中注入一些javascript,以便它附加到InlineScript集合的末尾。

所以我在动作视图中写道:

<?php $this->InlineScript()->offsetSetFile(100,$this->basePath() . '/js/xyz.js'); ?>

但结果是文件xyz首先在渲染视图中加载。

我正在使用Zend Framework 2.0.5

有人可以给我建议如何管理吗?

4 个答案:

答案 0 :(得分:13)

只是为了补充这个老问题:

内部视图: 在页面顶部附加文件

$this->headScript()->appendFile('/js/filename.js');

在页面顶部附加脚本

$this->headScript()->appendScript('alert(1)');

在页面底部附加文件

$this->inlineScript()->appendFile('/js/filename.js');

在页面底部附加脚本

$this->inlineScript()->appendScript('alert(1)');

内部控制器/操作

使用serviceLocator抓取Headscript,其余的是相同的

$this->getServiceLocator()
    ->get('viewhelpermanager')
    ->get('HeadScript')->appendScript('alert(1)'); //or ->appendFile('/js/filename.js');

如果您知道如何在操作中获取inlineScrip,请告诉我们。

答案 1 :(得分:2)

这似乎是由您在布局中使用appendFile引起的。首先运行视图脚本,然后将脚本附加到堆栈。然后,在运行布局时,再次追加,使布局中的脚本成为最后一个。尝试在布局文件中使用prependScript,以使布局中的脚本不会附加到已添加的脚本中。

答案 2 :(得分:1)

我知道这是一个古老的问题,但这个解释可能非常有用(我以前在这个问题上毁了我的头......)

让我们从一个案例开始:

您有4个脚本要追加到页面中。
2在您的布局中定义,2在您的视图中定义。
让我们将它们命名为script1,script2,script3和script4(最终的顺序应该尊重numerotation)。

布局:

<?php
    $this->inlineScript()->prependFile('script2.js')
                         ->prependFile('script1.js');

查看:

<?php
    $this->inlineScript()->appendFile('script3.js')
                         ->appendFile('script4.js');

结果:

<script type="text/javascript" src="/script1.js"></script>
<script type="text/javascript" src="/script2.js"></script>
<script type="text/javascript" src="/script3.js"></script>
<script type="text/javascript" src="/script4.js"></script>

发生了什么事?

首先,处理视图,脚本(在视图中)被添加到堆栈中,所以我们有:

附加

script3

[script3.js] <--
附加

script4

[script2.js]
[script3.js] <--

然后,处理布局,并以相反的顺序添加脚本,以便:

script2前置:

[script2.js] <--
[script3.js]
[script4.js]

script1前置:

[script1.js] <--
[script2.js]
[script3.js]
[script4.js]

答案 3 :(得分:0)

我正在解决问题:“如果你知道如何在行动中获取inlineScrip请告诉我们。”,得到了一个非常好的解决方案并决定在此发布:

  1. 创建一个在其他地方调用的小类,将所有内联脚本分组,并正确格式化以便由layout.phtml模板呈现
  2. 定义条件插入点以在最终页面中注入完整脚本
  3. (我替换代码04-05-2016因为原版输入错误)         

        <?php
            // Filename: /module/MyTools/src/MyTools/Library/Js2ls.php
            namespace MyTools\Library;    
            abstract class Js2l
    {
        protected static $inLineJs;
        protected static $inLineVars;
    
        public static function addSetting($settingkey, $settingvalue)
        {
            if(!self::isSettingThere($settingkey)){
                self::$inLineVars[$settingkey] = $settingvalue;
            }
        }
    
        public static function addScript($script, $scriptkey=NULL)
        {
            if(!$scriptkey){
                if(!self::$inLineJs){
                    self::$inLineJs = array();
                    self::$inLineJs[] = $script;
                }elseif(!(in_array($script, self::$inLineJs))){
                    self::$inLineJs[] = $script;
                }
            }elseif(!isset(self::$inLineJs[$scriptkey])){
                self::$inLineJs[$scriptkey] = $script;
            }
        }
    
        protected static function appendItemToSetting($current, $item)
        {
            if($item == $current){ return $current; }
            if(is_array($current)){
                if(!in_array($item, $current)){                
                    $current[] = $item;
                }
                return $current;
            }else{
                return [$current, $item];
            }
        }
    
        public static function extendSetting($settingkey, $settingvalue)
        {
            $current = self::getSetting($settingkey);
            if($current){
                $new = self::appendItemToSetting($current, $settingvalue);
                if( $new !== $current){
                    self::$inLineVars[$settingkey] = $new;            
                }
            }else{
                self::addSetting($settingkey, $settingvalue);
            }
        }
        public static function getSetting($settingkey){
            if(self::$inLineVars){
              $sale = isset(self::$inLineVars[$settingkey]) ? self::$inLineVars[$settingkey] : NULL;
              return $sale; 
            }else{
              return NULL;
            }
        }
    
        public static function getScripts(){
          return self::$inLineJs;
        }
    
        public static function getSettings(){
          return self::$inLineVars;
        }
    
        public static function iskeyedArray($array)
        {
            $out = FALSE;
            $keys = array_keys($array);
            foreach ($keys as $key) {
                if(!is_numeric($key)){
                    $out = TRUE;
                    break;
                }
            }
            return $out;
        }
    
        protected static function renderInLineJs()
        {
            return (self::$inLineJs) ? implode("\n", self::$inLineJs) : '';
        }
    
        protected static function renderInLineVars($js)
        {
            $out = '';
            if(is_array($js)){
                $items = [];
                foreach ($js as $key => $value) {
                    $items[] = '"'.$key .'": '.self::renderJsItem($value);
                }
                $out .= implode(', ', $items);
            }        
            return $out;
        }
    
        protected static function renderJsItem($item)
        {
            if(is_scalar($item)){
                return (is_numeric($item)) ? ''.$item : '"'.$item.'"';
            }elseif(is_array($item)){
                if(self::iskeyedArray($item)){
                    return '{'. self::renderInLineVars($item).'}';
                }else{
                    return (count($item)>0) ? '["'.implode('", "', $item).'"]' : '[ ]';
                }
            }else{
                return '[ ]';
            }
        }
    
        protected static function isSettingThere($settingkey)
        {
            return ( isset(self::$inLineVars[$settingkey]) ) ? TRUE : FALSE;
        }
    
        public static function ToString()
        {
            $prefix = "\n".'jQuery.extend(MyTools.settings, {';
            $suffix = '});'."\n";
            $settings = self::renderInLineVars(self::$inLineVars);
            $jsSettings = ($settings) ? $prefix.$settings.$suffix: '';
            $jsMethods = self::renderInLineJs();
            return ($jsMethods) ? $jsSettings."\n".$jsMethods : $jsSettings;
        }
    }
        ?>
    
    </code>
    
    Whit this class defined you can add, elsewhere,  global variables to be used by your scripts to a global variable using the code:
    
    <code>
    
        <?php
        // you are elsewhere in your php code. Write
        use MyTools\Library\Js2l
        Js2l::addSetting($settingkey, $settingvalue);
        // or
        Js2l::extendSetting($variablename, $value);
        // $settingvalue and $value can be scalar o array values
        Js2l::addScript($yourJavaScript, $akeyToAvoidDuplicates);
        ?>
    
    </code>
    
    The class knows how to format the code so you can call it to be injected in the template
    
    <code>
        <?php
        // Filename: /module/Application/view/application/layout/layout.phtml
        ?>
    
        <?php
        // place this call before the scripts block
        use MyTools\Library\Js2l
        $mysript = Js2l::ToString();
        if ($mysript){
          echo $this->inlineScript()->appendScript($myscript);
        }
    
    </code>
    

    现在您有了一个有用的类来按需插入内联脚本。