2012-07-25 23 views
2

像這樣:基於服務器端邏輯認爲有害的迴應Javascript代碼嗎?

<script> 
    setSomeStuffUp(); 

    <?php if ($otherStuffNeedsToBeDone === true) { ?> 

     doSomeOtherStuff(); 

    <?php } ?> 

    breakSomeStuffDown(); 
</script> 

跨越這樣的事情來了在用模板(Smarty的)做與工作,所以它看起來有點清潔劑 - 但不是很多!還回應了一些用於諸如jQuery選擇器等事物的模板變量,以及其他一些令人不快的外觀。

這樣做的正確方法是什麼?通過AJAX將需要用於JS中邏輯的數據加載爲JSON? HTML數據屬性?

有些東西只是味道不好,壞,壞。

謝謝大家。

+0

我通常不會那樣做我自己的東西,但一直都在看,並且據我所知,使用服務器端語言輸出javascript或其他任何事情都沒有錯,一個是在服務器上,另一個在客戶端,他們並沒有真正的互動。 – adeneo 2012-07-25 21:08:43

+0

不要看到有什麼問題。 – OrangeDog 2012-07-25 21:08:55

+2

我沒有看到任何問題,但我盡我所能遠離它,以保持客戶端和服務器端之間的分離。 – 2012-07-25 21:10:26

回答

4

這是不好的做法,使用X語言的語言Y.

嘗試「脫鉤」,這兩種語言來生成代碼,例如,像這樣:

<script type="text/javascript"> 
    var data = { 
    id: "<?php echo $id ?>", 
    ... 
    }; 

    $(document).ready(function(){ 
    $("#" + data.id).on("click", function(){ 
     /*do something*/ 
    }); 
    }); 
</script> 

這樣,PHP只在乎關於填充數據結構和JavaScript只關心消費數據結構。

+0

+1基本上是對這個問題可能的最好和最簡潔的答案。儘可能多地保留靜態的JS代碼,並儘可能動態地生成數據結構。 – Spudley 2012-07-25 21:17:42

+0

嚴格來說,這並不是將兩種語言解耦。 – Mahn 2012-07-25 21:17:46

+0

@Mahn這就是爲什麼我用報價。 – 2012-07-25 21:19:00

1

如果您所做的只是將數據從服務器端語言傳遞到JavaScript代碼,那很好。大量的CMS包在那裏做。

我真的不需要有條件地在服務器端生成JavaScript代碼。也許有一個用例,但JavaScript本身就是一種語言,那麼爲什麼不把邏輯放在JavaScript代碼中呢?

3

從服務器迴應配置變量和一些JavaScript初始化代碼通常聽起來不會太糟糕,但如果這樣的話,那麼你是對的,這很醜陋,至少因爲這樣的代碼難以管理。

只要嘗試集中任何類型的初始化,並在靜態定義的客戶端JavaScript邏輯中完成剩下的工作。

UPD。 @Oscar Jara正在談論同樣的事情,並提供了一個很好的例子。但是,如果服務器端邏輯通過HTML爲JavaScript處理提供數據(畢竟這是HTML的用途),通常甚至可以避免這種情況。

這是一個你可以經常遇到的簡單例子。假設您想要輸出一個將通過JavaScript增強爲旋轉木馬的圖庫。

服務器生成的HTML:

<ul id="myGallery"> 
    <li><img src="img1.jpg /></li> 
    <li><img src="img2.jpg /></li> 
    <li><img src="img3.jpg /></li> 
    ... 
</ul> 

然後你有你的靜態的JavaScript代碼初始化轉盤時,DOM已準備就緒:

// when DOM ready... 
AwesomeCarousel.init($('#myGallery')); 

這裏由服務器準備的數據是這一塊的HTML與圖像列表,不需要生成顯式加載每個圖像的JavaScript。您可以通過data-*屬性傳遞任意數據。

2

就我個人而言,我在許多情況下在JS中使用PHP。有時候是用JSON數據,頁面ID或者其他性質填充變量。就我而言,PHP旨在編寫出現在頁面上的代碼,並且JS被設計爲在內容存在時與用戶交互。

我確實知道你在說什麼,因爲這可能是更乾淨的方法。你提到了AJAX,它可能會更乾淨,並且肯定會有助於輸出文檔的流程。唯一的問題是,你必須向服務器發出第二個請求,以獲得一些非常簡單和有意義的變量。幾毫秒並不是很大,但在生產網站中,您可能不希望發出額外的請求並使服務器資源陷入困境。

爲了迴應最乾淨的做法,如果這是一筆大交易......我會用該代碼創建一個單獨的JS文件,然後根據需要使用服務器來包含該單個文件。再次,我不這樣做,但我認爲它會看起來最清潔的模板。

2

如果您想要真正實現這一功能,您可以讓HTML頁面請求一個.js文件,再加上他們的會話ID或其他一些指示他們的人,將.js調用操作爲PHP調用,根據會話需要動態構建JS,然後以.js文件類型的形式將其輸出回瀏覽器。

但這是很多工作。

如果你想的東西,氣味少,有PHP轉儲或者在你的文件的最後一個JSON字符串:

var cfg_string = "{\"username\":\"Norguard\", \"new_messages\":[......]}"; // client 

$cfg_obj = array(); // whole lot o'PHP 
$json_encoded_cfg = json_encode($cfg_obj); 
echo "var cfg_string = {$json_encoded_cfg};" //server-side 

,然後分析它,在客戶端增加安全性...

...或只是直接創建模板的地圖:

$cfg_string = "var dataMap = {"; 
foreach ($cfg_obj as $key => $val) { 
    // print key:val all pretty-like, 
    // handle commas (ie: no trailing comma at the end), indent with tabs or spaces 
    // if you want, count the number of items so that the object closes ({}) 
    // without any newline operator, if there are no config settings 
} 
echo $cfg_string; 

這兩者都是乾淨,不顯眼,並保留一切分開。 配置數據/文本可以在正確的init/loading代碼之上進行,並作爲參數傳遞給該init-logic。