2012-02-11 14 views
1

我目前正在開發symfony2應用程序並使用嵌入式控制器。我的嵌入式控制器就像小部件一樣,它應該封裝自己的一套功能,並且可以嵌入到任何地方,並且仍然可以運行。帶資產的嵌入式控制器視圖

我有一個控制器在線調用用戶。它生成的視圖很簡單,只是一個在線用戶列表。但是,我想向該視圖添加一些JavaScript,以便我可以使用ajax檢索單擊用戶的信息。

控制器基本上返回一個視圖:

return $this->render('AppBundle:Users:usersOnline.html.twig', array('somedata' => $data); 

下面是該控制器的視圖:

{% extends partial.html.twig" %} 
{% block content %} 
<ul> 
    <li><a href="site.com/ajax/user/1">User 1</a></li> (this would all be generated using 'somedata') 
    <li><a href="site.com/ajax/user/2">User 2</a></li> 
    .... 
<ul> 
{% endblock content %} 
{% block scripts %} 
    ..some javascript for interacting with this widget 
{% endblock %} 

這是從延伸部分:

{% block content %} 
{% endblock content %} 

{% block scripts %}{% endblock %} 

這裏的嵌入控制器的主頁面:

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block content %} 
..some markup here 
<div id="usersonline"> 
    {% render "AppBundle:Users:usersOnline" with {'max': 4} %} 
</div> 
{% endblock %} 

{% block scripts %} 
    ..some javascript 
{% endblock %} 

這是,它的延伸基:

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>{% block title %}{% endblock %} - App</title>  
    ...Some stylesheets 
    </head> 
    <body> 
     {% block content %}{% endblock %} 
     <script src="http://yui.yahooapis.com/3.5.0pr2/build/yui/yui-min.js"></script> 
     {% block scripts %}{% endblock %} 
    </body> 
</html> 

我現在面臨的問題是從包括嵌入式控制器的JavaScript。在我的情況下,視圖部分擴展並在插入主頁之前完全呈現爲1個單元。在這種情況下,我只能將我的javascript放在content塊中,這意味着我將在<div>標籤內有<script>標籤。我還希望在用戶界面性能的主體末尾有腳本。

我應該如何構建我的模板(或甚至可能),以便可以將嵌入控制器的模板中適當的塊從嵌入式控制器的視圖中渲染爲適當的塊?在我當前的模板中,YUI庫將在嵌入式控制器呈現的HTML標記之後加載,因此在嵌入式控制器內使用YUI庫是不可能的。

+0

[Duplicate](http://stackoverflow.com/q/9224347/1146363)雖然更易於閱讀。我不認爲嵌入式控制器的結果可以在多個塊之間分配。返回的結果只是呈現的html而不是樹枝模板。我認爲你需要兩個嵌入式控制器,一個用於內容,另一個用於JavaScript。在某些情況下,甚至可能只有一個用於CSS。 – Cerad 2012-02-11 14:17:39

+0

嗯。擁有2個嵌入式控制器不太理想,而且不是很優雅的imo。 – F21 2012-02-12 04:13:14

+0

那麼你實際上並不需要兩個控制器,只需要兩個調用同一個控制器的參數,該參數指定你想要的內容,即{'generate':'html'或'js'或'css'}。然後相應地調整你的模板。 – Cerad 2012-02-12 13:10:03

回答

0

我寫了一個擴展,它本質上是一個令牌解析器來處理這個問題。令牌解析器的文檔非常稀少,並且代碼也大部分是未註釋的,因此需要花費一些時間才能開始工作。

我已經構造的解析器,以便在一開始,你就宣告的東西(類同{% use %}):

{% myparser "AppBundle:Users:usersOnline" with {'max': 4} as xyz %} 

然後,像xyzcontent塊是avaliable,然後你只使用使它們在合適的地方{{block('xyzcontent')}}。它工作得很好。但是,以下內容不起作用:

{% set max = 4 %} 
{% myparser "AppBundle:Users:usersOnline" with {'max': max} as xyz %} 

我找不到一種方法來評估表達式並直接在令牌解析器中獲取其值。大多數情況下,它工作正常,除了這個問題。

如果有人有一些想法,如何獲得令牌解析器中的變量的值,這將是巨大的:)

+0

我拼命尋找類似問題的解決方案:在我的情況下,我正在寫一個能夠嵌入多個控制器(這意味着包括其他模板)的'小部件'包,但我希望能夠'註冊' ('樣式表'/'javascripts')的資產(js/css/less)。無論如何,你能分享你的Twig擴展代碼嗎?編寫我自己的令牌解析器非常困難(沒有經驗)。謝謝你的優勢。 – 2013-03-06 20:45:21

0

尋找一個令人滿意的解決方案一天後,我終於選擇以下方法:

  • 爲你的小部件的功能呈現一個控制器(就像你已經在做);
  • 渲染模板以嵌入您的小部件的資產(不需要控制器,會浪費您的性能)。忽略包含模板不存在的情況。
  • 使用一致的命名約定可使窗口小部件功能更具動態性。

舉例一個小部件:

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block content %} 
..some markup here 
<div id="usersonline"> 
    {{ render(controller("AppBundle:Users:usersOnline", {'max': 4})) }} 
</div> 
{% endblock %} 

{% block scripts %} 
    {{ include("AppBundle:Users:usersOnline_js.html.twig" ignore missing }} 
{% endblock %} 

{% block stylesheets %} 
    {{ include("AppBundle:Users:usersOnline_css.html.twig" ignore missing }} 
{% endblock %} 

(正如你看到的,我使用的包括和嵌入的Symfony的2.2方式)

或者小部件呈現一個更加動態的方式:

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block widgets %} 
..some markup here 
    {% for widget in widgets %} 
    {{ render(controller(widget.controller ~ ':widget', widget.options)) }} 
    {% endfor %} 
{% endblock %} 

{% block scripts %} 
    {% for widget in widgets %} 
    {{ include(widget.controller ~ ':widget_js.html.twig' ignore missing }} 
    {% endfor %} 
{% endblock %} 

{% block stylesheets %} 
    {% for widget in widgets %} 
    {{ include(widget.controller ~ ':widget_css.html.twig' ignore missing }} 
    {% endfor %} 
{% endblock %} 

我的結論

在一個頁面中渲染多個控制器,而「合併」模板塊時,無法在Symfony2中實現。 Symfony2一直專注於每個請求的一個控制器,這就解釋了爲什麼多個控制器輸出分離並難以組合。

我認爲Symfony CMF已經(或將要)爲此提供了一個合適的解決方案,因爲整個小部件主題更多地應用於動態內容託管網站。

無論如何,我認爲我的方式結合嵌入式控制器和包含的模板是目前爲止Symfony 2的最佳方法。

的替代品,在我看來,確實有許多缺點:

  • 使用多個控制器:過重,而不是必要的,因爲資產將不需要任何控制器。
  • 直接在頁面中加載小部件資產:更改小部件/資產時很難維護。
相關問題