簡體   English   中英

Angular JS和Symfony2

[英]Angular JS and Symfony2

我目前正在使用Symfony2進行一個項目,並就此尋求一些建議。

我正在考慮以兩種不同的方式使用混合應用程序a)登錄頁面應使用帶CRF令牌的傳統形式,並讓symfonty2處理它。 b)所有內頁(可能是模塊)我希望它們是非AJAX,但其中的其他活動應該像單頁一樣。

例如,我有一個員工模塊 當用戶點擊它完全從服務器(所有模板和表單等)加載時,現在員工模塊下的每個活動(如添加/更新刪除/視圖等)都將通過AJAX加載,並且響應將以JSON(即AngularJS)返回。

我目前正在考慮使用FOSUserBundle在初始請求時返回html然后根據請求類型接受:application / json它將返回JSON(還記得add / updat delete / view部分嗎?)。

我的問題是使用Angular Partials(html)文件或Symfony2 Twig更好嗎? 或者使用Angular JS會更好,但是讓那些部分由Symfony2 twig渲染? (我在想這里的Forms,想要從客戶端和服務器端驗證)

有沒有人經歷過類似的問題,如果是,那么使用AngularJS和Symfony2或任何其他框架開發HYBRID應用程序的方法是什么? 任何相關的想法表示贊賞。

我和你的情況一樣。 AngularJS + Symfony2項目,REST API,使用FOSUserBundle登錄等。

......各方面都有利有弊,所以沒有正確的方法,我只想說出我的所作所為。

我選擇AngularJS本機模板,沒有CSRF驗證,使用Twig構建的基本模板,服務器端驗證,使用FOSJSRoutingBundle以及一些幫助程序(BuiltResponse和BaseController)。

為什么原生模板?

通過逐字使用,我們解決了變量問題,但是我們的模板中會有更復雜的邏輯。

我們的應用程序也將具有不太可擴展性。 我們所有的表單模板都在Symfony應用程序中執行請求,AngularJS的最佳專業人員之一是從存儲服務(如S3)或CDN(如Cloudfront)加載我們的控制器,模板等。 由於沒有服務器端處理,我們的模板加載速度會快得多。 即使有緩存,Twig顯然也比較慢。

根據我自己的經驗,Twig和AngularJS模板都非常復雜。 我開始將它們組合在一起,但管理起來很痛苦。

我做了什么?

我在前端創建了靜態模板,使用相同的字段名稱,這不是很好。 我們需要在每次手動更新表單時更新模板。 但這是我發現的最佳方式。 由於字段名稱相同,我們在調整Angular控制器中的模型名稱時不會遇到任何問題。

如果您要將軟件創建為服務,則無論如何都需要執行此操作。 你不會在移動應用程序中加載應用程序中的表單模板嗎?

為什么沒有CSRF驗證?

顯然,我們不在REST API中使用CSRF驗證。 但是,如果您想這樣做,則需要在每次加載表單時發出請求以獲取CSRF令牌。 這真的非常糟糕。 因此,我們創建了一個CRUD,我們還需要創建一個“csrf-CRUD”,更多4條路由。 這沒有任何意義。

我做了什么?

我在表單中禁用了CSRF。

基本模板?!

是的。 基本模板只是在我們的應用程序中加載任何路由。 這是我正在做的事情:

在此輸入圖像描述

如果您使用的是html5 angularjs網址,這將有助於我們避免在用戶直接訪問某些應用程序URL時出錯。 很簡單。

服務器端驗證,為什么?

如果我們在Angular中進行驗證,我們需要在服務器端執行相同的操作,因此我們需要維護2個驗證代碼。 那很痛苦。 我們在表單中進行的每一項更改,都需要更改前面的驗證,后面的驗證以及Angular靜態表單。 真的,真的很痛苦。

我做了什么?

我基本上使用Symfony約束進行了服務器端驗證。 對於每個請求,應用程序驗證表單並檢查是否發現任何錯誤,如果是,則獲取第一個並將其作為響應發送。

在AngularJS中,應用程序檢查錯誤鍵內是否有任何錯誤。 因此,我們在所有應用程序中都使用了一個進程來執行任何表單請求。 就像那樣:

在此輸入圖像描述

和路線?

還有另一個問題:路線。 直接放url是不可靠的方法。 如果我們更改了網址中的任何內容,那么該路由就會消失,用戶也不會喜歡。

為了解決這個問題,我們可以使用FOSJsRoutingBundle 使用該庫,我們可以將路徑名稱直接放在Angular控制器中,它將填充路徑的確切URL。 它與Symfony完全集成,因此參數可以很好地工作。

而是直接使用url,我們可以這樣做:

Routing.generate('panel_products_show', {id: $routeParams.product_id});

瞧! 我們得到路線網址。


這將解決您遇到的最大問題。 但還有更多。

問題1 - 表格輸入

Symfony中的表單通常有一個前綴,如“publish_product”,因此每個字段都有一個名稱,如[publish_product]name 啊,這對我來說是怎么回事。

在Angular中,publish_product不被視為數組。 您需要使用單引號來執行此操作,例如['publish_product']name 這真的很糟糕,我們需要更改每個鍵才能使用這種格式。 在AngularJS中,我這樣做:

{{ formData('[publish_product]name') }}

絕對愚蠢。

最好的解決方案是簡單地刪除Symfony中的表單前綴,使用createNamedBuilder方法而不是createBuilder 我讓第一個參數為null,是的,我們不再需要使用前綴了。 現在,我們使用:

{{ formData.name }}

好多了。

問題2 - 路線很難維護

每個請求都可以返回任何內容,我需要重復很多代碼。 這真的很難維護,所以我只創建一些應用程序規則,構建響應,BaseController等。

createNamedBuilder

createNamedBuilder是一個createNamedBuilder的方法。 對於我們擁有的每種形式,我們都需要這樣做:

在此輸入圖像描述

解決起來很簡單。 我剛剛創建了一個BaseController,我正在擴展它的每個控制器。 我創建了一個簡單的方法來完成它。

在此輸入圖像描述

對於每條路線,我們不需要重復3條線,更好。

回應

當我的應用程序開始增長時,我遇到了一個嚴重的問題:我的所有回答都不同。 這真的很難維持。 對於我正在做的每個請求,有時我使用“響應”,有時“數據”,錯誤消息在響應中丟失等。

所以,我決定創建一個buildResponse,我只需要設置一些參數,每個路由都得到相同的結果,甚至是GET路由。

在此輸入圖像描述

response鍵顯示狀態和消息。 它可能是錯誤或成功,並且消息是可選字段,可以是空白的。 例如,成功狀態,顯示消息“您創建了產品”。

data鍵顯示我需要的任何信息。 例如,用戶添加了產品,現在他需要鏈接才能看到它。 在數據中,我把帖子的url,我很容易從AngularJS控制器獲取它。

notifications是我的業務邏輯的特定鍵。 每個操作都可以向用戶返回通知。

你有什么鑰匙並不重要。 最重要的是有一個標准化的響應,因為當你的應用程序增長時,它將非常有用。

這是我的控制器的路線:

在此輸入圖像描述

完全標准化。 Scrutinizer代碼質量工具說我的所有路由都是重復的。 :d

有一個BaseController和一個builtResponse會幫助你這么多。 當我開始重構我的代碼時,每條路線丟失了大約4-10行。


詳細信息: getFormError返回表單的第一個錯誤。 這是我的方法:

public function getFormError(FormInterface $form)
{
    if ($form->getErrors()->current()) {
        return $form->getErrors()->current()->getMessage();
    }

    return 'errors.unknown';
}

...而buildResponse的參數是:1。狀態。 我從BaseController中的常量中得到它。 它可以改變,所以我認為重要的是不要在每條路線中使用字符串值。 2.翻譯信息。 (我使用preg_match來檢查它是否有翻譯格式,因為getFormError已經轉換了錯誤)。 3.數據(數組)參數。 4.通知(數組)參數。

我還有其他問題

到目前為止,該項目只有一種受支持的語言。 當我開始使用多語言版本時,我將遇到另一個大問題:維護兩個版本的翻譯:后端消息和驗證以及前端的文本。 這可能是個大問題。 當我得到最好的方法時,我會更新這個答案。

我花了幾個月才得到這種方法。 如此多的代碼重構和未來可能會更多。 所以我希望它可以幫助別人不需要這樣做。

如果我有更好的方法來做到這一點,我會更新這個答案。

我不擅長寫英文,所以這個答案可能會有許多語法錯誤。 對不起,我正在修理我所看到的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM