问题
I'm working with Zend Framework 2.
In my Layout File i inject some javascript files like this:
$this->InlineScript()
->appendFile($this->basePath() . '/js/myfile.js');
echo $this->InlineScript();
Now i want to inject some javascript from a view so that it appends to the end of the InlineScript Collection.
So i wrote this in my action view:
<?php $this->InlineScript()->offsetSetFile(100,$this->basePath() . '/js/xyz.js'); ?>
But the result is the File xyz is loaded first in the rendered view.
I'm working with Zend Framework 2.0.5
Does anybody can give me an advise how to manage this ?
回答1:
Just to complement this old question:
Inside View: Append a file at the top of the page:
$this->headScript()->appendFile('/js/filename.js');
Append a script at the top the page
$this->headScript()->appendScript('alert(1)');
Append a file at the bottom of the page:
$this->inlineScript()->appendFile('/js/filename.js');
Append a script at the bottom of the page
$this->inlineScript()->appendScript('alert(1)');
Inside Controller/Action
Grab Headscript using serviceLocator and the rest is the same
$this->getServiceLocator()
->get('viewhelpermanager')
->get('HeadScript')->appendScript('alert(1)'); //or ->appendFile('/js/filename.js');
If you know how to get inlineScrip inside an action please let us know.
回答2:
This seems to be caused by using appendFile within your layout. Your view script is run first in which you append a script to the stack. Then, when your layout is run, you append again, making the script from your layout the last one. Try to use prependScript in your layout file such that the script from your layout is not appended to the already added scripts.
回答3:
I know this is an old question but this explanation could be really useful (I ruined my head with this problem some times ago..)
Let's start with a case :
You have 4 scripts to append in a page.
2 are defined in your layout and 2 in your view.
Let's name them script1, script2, script3 and script4 (final order should respect numerotation).
Layout :
<?php
$this->inlineScript()->prependFile('script2.js')
->prependFile('script1.js');
View :
<?php
$this->inlineScript()->appendFile('script3.js')
->appendFile('script4.js');
Result :
<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>
What's happened ?
First, the view is processed, scripts (in the view) are appened in the stack, so we have :
script3 is appended :
[script3.js] <--
script4 is appended :
[script2.js]
[script3.js] <--
Then, the layout is processed, and script are prepended in reverse order so :
script2 is prepended :
[script2.js] <--
[script3.js]
[script4.js]
script1 is prepended :
[script1.js] <--
[script2.js]
[script3.js]
[script4.js]
回答4:
I was working around the questión : "If you know how to get inlineScrip inside an action please let us know.", got a pretty solution and decided to post it here:
- Create a small class to be called elsewhere to group all your inline scripts, and format them properly to be rendered by layout.phtml template
- Define a conditional inserting point to inject the full scripts in your final page
(I replace the code 04-05-2016 because original was mistyped)
<?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>
Now you have an useful class to insert your inline scripts on demand.
来源:https://stackoverflow.com/questions/14772376/append-javascript-file-to-the-end-of-the-inlinescript-collection-from-child-view