5

我正在使用 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

4 回答 4

14

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

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

$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,请告诉我们。

于 2013-09-24T20:00:21.247 回答
2

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

于 2013-02-08T12:36:55.070 回答
1

我知道这是一个老问题,但这个解释可能真的很有用(我前段时间被这个问题搞砸了......)

让我们从一个案例开始:

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

布局 :

<?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]
于 2016-05-04T10:32:58.933 回答
0

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

  1. 创建一个在别处调用的小类来对所有内联脚本进行分组,并正确格式化它们以由 layout.phtml 模板呈现
  2. 定义一个条件插入点以在最终页面中注入完整的脚本

(我替换了代码 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>

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

于 2016-05-04T05:19:34.097 回答