2011-01-27 21 views
4

我正在創建一個PHP框架,它允許PHP開發人員創建僅包含PHP類的ExtJS前端,例如,創建網格看起來是這樣的:從PHP生成Javascript/ExtJS代碼的最可維護的方法是什麼?

$grid_import = new Backend_Layout_Grid('smart_worksheets'); 
$grid_import->set_width(1300); 
$grid_import->set_rows_selectable(true); 
$grid_import->set_title(__('backend.application.import.grid.title')); 
$grid_import->set_margin('10px'); //CSS syntax, e.g. also "10px 0 0 0" 
$grid_import->add_column(array('id_code'=>'name', 'label'=> __('backend.application.import.worksheetstoimport'), 'width'=>'300')); 
$grid_import->add_column(array('id_code'=>'kind', 'label'=> __('backend.application.import.kind'), 'width'=>'50')); 
$grid_import->add_column(array('id_code'=>'file_size', 'label'=> __('backend.application.import.sizebyte'), 'datatype' => 'int')); 
$grid_import->add_column(array('id_code'=>'when_file_copied', 'label'=> __('backend.application.import.whenfilecopied'), 'datatype' => 'datetime', 'width'=>'150')); 
$grid_import->add_column(array('id_code'=>'table_name', 'label'=> __('backend.application.import.mysqltablename'), 'width'=>'300')); 
$grid_import->add_column(array('id_code'=>'when_table_created', 'label'=> __('backend.application.import.whentablecreated'), 'width'=>'160')); 
$grid_import->add_column(array('id_code'=>'status', 'label'=> __('backend.application.import.status'), 'width'=>'300')); 

$grid_import->set_doubleclick_target_uri('backend/application/importmanager/single', 0); 

if (count($smart_worksheets) > 0) 
{ 
    $row_index = 0; 
    foreach ($smart_worksheets as $smart_worksheet) 
    { 
     $show_row = array(
      'name' => $smart_worksheet['name'], 
      'kind' => $smart_worksheet['kind'], 
      'file_size' => $smart_worksheet['file_size'], 
      'when_file_copied' => $smart_worksheet['when_file_copied'], 
      'table_name' => $smart_worksheet['table_name'], 
      'when_table_created' => __($smart_worksheet['when_table_created']), 
      'status' => __($smart_worksheet['status']) 
     ); 
     $grid_import->add_row($show_row); 
     if(in_array($smart_worksheet['status'], array('backend.application.import.status.needtoimport', 'backend.application.import.status.needtoreimport'))) { 
      $grid_import->add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_RED); 
     } 
     if(in_array($smart_worksheet['status'], array('backend.application.import.status.isuptodate'))) { 
      $grid_import->add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GREEN); 
     } 

     if(intval($smart_worksheet['file_size']) > 4000000 AND (in_array($smart_worksheet['kind'], array('XLS','XLSX')))) 
     { 
      $grid_import->add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GRAY); 
     } 

     $row_index++; 
    } 
} 

Backend_Layout_Window::instance()->add_item($grid_import); 

它運作良好,到目前爲止,但因爲我剛剛輸出的JavaScript代碼行由行,更多的功能我打造成了一流的,越複雜的if/then邏輯妨礙我們構建的原始的Javascript文字,這裏是一個典型的方法生成的Javascript代碼:

public function render_main_code_block() 
{ 
    $retval = ''; 

    $retval .= $this->render_data_variable(); 
    $retval .= $this->render_array_reader_block(); 
    $retval .= $this->render_grid_panel_block(); 


    if($this->rows_selectable) 
    { 
     $retval .= self::render_line("````}),"); 
     $retval .= self::render_line("````sm: sm,"); 
    } 

    $retval .= self::render_line("````viewConfig: {"); 


    if ($this->percentage_columns) 
    { 
     $retval .= self::render_line("``````forceFit: true,"); // true = percentage column width (add up to 100) 
    } 
    else 
    { 
     $retval .= self::render_line("``````forceFit: false,"); 
    } 

    $retval .= self::render_line("``````getRowClass: function(record, rowIndex, rp, ds){"); 
    if (count($this->row_formats) > 0) 
    { 
     foreach ($this->row_formats as $row_index => $row_format) 
     { 
      $retval .= self::render_line("````````if(rowIndex == ".$row_index."){"); 
      $retval .= self::render_line("``````````return '".$row_format."';"); 
      $retval .= self::render_line("````````}"); 
     } 
    } 
    $retval .= self::render_line("````````return '';"); 
    $retval .= self::render_line("``````}"); 
    $retval .= self::render_line("````},"); 

    $retval .= self::render_line("````title: '$this->title',"); 
    if (! is_null($this->width)) 
    { 
     $retval .= self::render_line("````width: $this->width,"); 
    } 
    $retval .= $this->render_double_click_handler(); 
    $retval .= self::render_line("````autoHeight: true,"); 
    $retval .= self::render_line("````frame: true"); 
    $retval .= self::render_line("``});"); 
    $retval .= self::render_line(""); 

    $retval .= self::render_line("``replaceComponentContent(targetRegion, ".$this->script_variable_name.");"); 
    $retval .= self::render_line("``".$this->script_variable_name.".getSelectionModel().selectFirstRow();"); 


    // for word wrapping in columns 
    $retval .= self::render_line("``function columnWrap(val){"); 
    $retval .= self::render_line("````return '<div style=\"white-space:normal !important;\">'+ val +'</div>';"); 
    $retval .= self::render_line("``}"); 

    return $retval; 
} 

這開始讓這段代碼過於複雜而無法維持一些具體問題是:

  • 一個簡單的事實,在物業清單中,只有最後一項沒有逗號。到目前爲止,我已經能夠將所需的屬性放在列表的末尾,以便不包含逗號的項目始終包含在內。

enter image description here

  • 和某些功能(如添加複選框,以網格或沒有)需要在JavaScript代碼多達四個不同的地方的代碼插入,我能想象有特色這將需要重新構建現有的代碼,所以如果功能打開,周圍的代碼需要例如包含的對象

所以在某些時候我想重構我創建了JavaScript的方式的另一部分中。

我目前只看到其中一個選項真的是,一個CodeFactory類,它包含例如ExtJsVariable我向其中遞歸地添加包含對象的對象,對象可以是例如類型的。 simpleArrayanonymousFunction等,然後創建代碼,我將輸出$codeFactory->render()這會給我根據其所有的內部對象的代碼:

enter image description here

什麼是其他選項或我可以使用代碼生成的框架使PHP中的這個Javascript/ExtJS代碼更加可維護,更直接?

+1

也許http://www.ext4yii.com/會給你更多的信息。 – Gajahlemu 2011-01-27 13:41:12

回答

0

實際上,我一直在通過類似的方式從PHP創建ExtJS代碼,或者從CakePHP創建ExtJS代碼。在我的公司,我負責創建應用程序框架,這將加快應用程序的生產,所以我實際上出來了我們的第一代框架,這與您的想法類似:通過PHP生成代碼。

然後很快我意識到,這是非常沉重的服務器,並緩慢。您獲得的每個請求都需要重新生成代碼,這是不切實際的。不久之後,我與第二代合作,具有緩存能力。生成的JS代碼被緩存到靜態文件中,並在需要時動態包含。緩存的原因是因爲大部分時間JS代碼是靜態的,變化是內容,商店等。

所以這種方法可以工作幾個月,直到我終於意識到這不是正確的方式,例如,

  • TreePanel不能通過這種方式生成,特別是使用動態菜單。
  • ACL不能干擾緩存代碼
  • 不能有網格
  • 我的框架設計糟糕,我需要看到結果之前緩存代碼動態列 - 發展緩慢。
  • 難以維護,很難打電話。簡單的事情,如添加一個配置或刪除一個配置可能是乏味的。就像使用FormHelper來完成簡單的東西一樣非常繁瑣。

於是我完全重寫我的代碼基礎,重新設計的一切,直到我想出這個電流漂亮的ExtJS + CakePHP的框架,其中:

  • 通用的GridPanel /存儲/查看/分頁/編輯組件被創建,並且只需一些簡單的配置,就可以獲得一個完整的REST網格,它可以連接到Cake的控制器之一。在Cake中包含了特別設計的組件之一,並且只需幾行代碼即可創建完整的REST網格。
  • 特別設計的視口提供類似的外觀和感覺,用專門設計的TreePanel中(菜單),的TabPanel(內容)
  • 等衆多通用的,有用組分被包裝在一起,像精靈,FieldEditor,UserImport ...等。
  • 而且由於它們都是可擴展的ExtJS組件,您可以使用它,擴展它,完全自定義它以滿足您的任何需求。

對不起,如果這聽起來不正確,但個人我已經經歷了這一點,我真的不滿意從PHP生成代碼的結果。你基本上最終會讓整個過程變得複雜,或者慢下來。

對不起,我的英語不好。感謝您閱讀本文。

而且我不能分享我的代碼,也不能開源它,因爲它是公司財產的一部分。

0

我會提出一些建議,因爲我也做了一些這方面的工作。

首先移動儘可能多的,你可以到圖書館類 其次,你可以創建一個PHP數據結構和json_encode

把它變成一個JSON最後保持簡單!

2

最好的方法是儘可能避免JS生成動態,並將所有Javascript保留在靜態JS文件(工廠,建設者最有可能)。並用服務器生成的JSON數據提供給他們。這將嚴重改善結構,並使您的應用程序更易於維護。您可能想了解有關Factory和Builder模式的信息。

相關問題