Instant Porridge-jqGridを使用してCachéでCRUDを作成する

これは、表形式データjqGridを表示するためのJavaScriptプラグインを使用して、 インターシステムズCachéで Webアプリケーションを作成することです 。 プラグインはHabréでよく言及されるため、Cachéが使用する機能に主な注意が払われます。

jqGridを使用する利点

料理の構成 :データを含む保存されたクラス、ページクラス、データサービスクラス。 必要なライブラリとスタイルは、データ配信ネットワーク( CDN )および開発者のWebサイトから接続されているため、ローカルネットワークで動作する例では、これらのソースからダウンロードする必要があります。



警告 :例は可能な限りシンプルで、プラグインの機能のごく一部しか考慮されていませんが、慎重に文書化されていますが、まだ多くのコードがあります。



モデル



この料理の基本は、クラスmodel.personです。

Cachéスタジオでストアドクラスを作成します。 ファイル-作成-Cachéクラス

格納されたクラスmodel.personのソースコード
/// 単純なストアドクラス

クラス model.person Extends %Persistent %Populate ){



/// 名前-記入する関数を示します

プロパティ As %String POPSPEC = "Name()" );

インデックス



/// 誕生年

プロパティ としての 整数 MAXVAL = 2012 MINVAL = 1910 );



/// ごとの 検索が高速になります

年の インデックス 年[ タイプ =ビットマップ];



}


少数のテストインスタンスを生成します-スタジオの「出力」ウィンドウ(Alt + 2)に移動して実行します。

write ##class(model.person).Populate(100000)
      
      





表示する



データ表示ページ-必要なスタイルと補助ライブラリを備えたview.personクラスを作成しましょう。

view.personクラスのソースコード
 ///     <class>model.person</class> ///   <a href="http://www.trirand.com/blog/">jqgrid</a> Class view.person Extends %CSP.Page { /// node     Parameter DOMAIN = "person"; ///     ClassMethod OnPage() As %Status { &html<<!DOCTYPE html> <html lang="ru"><head> <meta charset="ru"/> <title>#($$$Text("Intersystems Caché + jqGrid"))#</title> <style> /*      */ body {font-size: 11px; font-family: Georgia,Verdana,Arial,sans-serif; } </style> <!--     --> <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.8.24/themes/base/jquery-ui.css" /> <!--     --> <link rel="stylesheet" type="text/css" href="http://www.trirand.net/themes/ui.jqgrid.css" /> <!-- ,    --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <!--   (, , etc.) --> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script> <!--    jgGrid--> <script src="http://www.trirand.net/js/trirand/i18n/grid.locale-ru.js"></script> <!--     --> <script src="http://www.trirand.net/js/trirand/jquery.jqGrid.min.js"></script> <!--    --> <script src="themeswitcher.js"></script> </head><body> <!--    c    --> <table id="grid"></table> <!--    --> <div id="bar"></div> <!--    --> <div id="theme"></div> <!--   --> <script type="text/javascript"> $( function(){ //  document.ready var $grid=$( "#grid" ) //     , bar="#bar" //    , url='#(..Link("service.person.cls"))#' ; $grid.jqGrid({ //  ,      caption: '#($$$Text("person"))#' , colModel: [ //    { name: 'name', width: 250, editable: true } ,{ name: 'year', editable: true } ] , pager: bar //      , url: url //  , editurl: url //    , datatype: "json" //    , mtype: 'POST' , jsonReader: { //     //      //      //       repeatitems: false } , height: 350, width: 900 //   , rownumbers: true //     , rownumWidth: 45 //       , viewrecords: true //      , gridview: true //   ,     , scroll: 1 //    , hoverrows: true //      , rowNum: 100 //   ,    , sortable: true //    , sortname: 'name' //      }) .jqGrid('filterToolbar',{searchOnEnter:false}) //  .jqGrid('gridResize', {}) //      ; ///        var serverHandler=function( resp ){ var array=[]; try { array=eval(resp.responseText); } catch(err){ return ["",e.description]; } return array; }; ///      / ,  var opts={ afterSubmit: serverHandler //    , closeAfterAdd: true //      , clearAfterAdd: true //       , closeAfterEdit: true //      //  .     .    , viewPagerButtons: false }; //    $grid.jqGrid('navGrid',bar, { edit: true, edittext: '#($$$Text(""))#' , add: true, addtext: '#($$$Text(""))#' , del: true, deltext: '#($$$Text(""))#' , view: false, search: false } , opts //  , opts //  , opts //  ); //     //   pager   $(bar+"_center").remove(); //  ,  UPD themeswitcher( $( "#theme" ) ); });</script></body></html>> Quit $$$OK } }
      
      





コントローラー



データサービスクラスのコードに進む前に、サーバーとプラグインデータを交換するためのプロトコルと形式について話す必要があります。 プラグインは、サーバーからデータの一部を非同期的にロードし、次のタイプのリクエストをサーバーに送信します。



?rows=100&page=2&_search=true&name=McCormick&sidx=name&sord=desc







ここで: rows-部分のデータ行数、 page-部分のシリアル番号、 _search-検索モード(オンまたはオフ)、McCormick-テーブルの列による検索値、 sidx-ソートフィールド、 sord-ソート順

応答として、jqGridは次のデータを予期します(たとえば、次のjsonデータ形式が選択されます)

 {"records": 102, "total": 2, "page": 2, "rows": [ { "id": 1,"name": "McCormick,Diane Z.", "year": 1910 } ,{ "id": 2,"name": "McCormick,Christen G.", "year": 1911 } ]}
      
      







where、 records-行の総数 、total-サーバー上のデータのチャンクの数、page-データのページ化されたチャンク、rows-データ配列



editurlパラメーターで指定されたアドレスに到着するプラグインからのデータを変更する要求は次のとおりです。



作成?oper=add&id=_empty&name=habra&year=2005





変更?oper=edit&id=1&name=habra&year=2006





削除?oper=del&id=1







これらの要求に対するサーバーの応答はafterSubmit関数で処理され、その結果は次の形式の配列になります。

[ result, error, id ]





ここで、resultはクエリの結果(true || false)、 errorはresult == falseの場合のエラーメッセージ、 idはオブジェクト識別子の値です(作成操作の場合)



このプロトコルはservice.personデータサービスクラスによって実装されます。このサービスクラスは、着信要求パラメーターを解析し、動的要求を生成し、特定の形式でデータを表示します。

クラスservice.personのソースコード
  #;    csp.inc #;      service.person ///      ///    %request #define get(%name) $g(%request.Data(%name,1))
      
      







 Include csp ///  -  Class service.person Extends %CSP.Page { /// node    Parameter DOMAIN = "person"; /// Can only be referenced from another CSP page Parameter PRIVATE = 1; ClassMethod OnPage() As %Status { #; . csp.inc set oper=$$$get("oper") ;   #;    -     if ( oper = "add" ) Quit ..Add() Q:oper="edit" ..Edit() Q:oper="del" ..Del() #;     -    #;          set rows=$$$get("rows")\1 ;  if ( rows < 1 ) { set rows = 100 ;       } #;       s page=$$$get("page")\1 s:page<1 page=1 #;     (   - ) #;  sql  where    s where="", params="", search=$CASE( $$$get("_search"), "true": 1, : 0 ) if ( search ) { s name=$$$get( "name" ) if ( name'="" ) { #;  name  ,     #;     s where=where_$ListBuild( "name Like ?" ) s params( $increment(params) )="%"_name_"%" } s year=$$$get( "year" ) if ( year'="" ) { #; year -   SQL -     s where=where_$LB( """year"" = ?" ) ;  -  , params( $i( params ) )=year\1 ; } s where=$ListToString(where," AND ") } #;      #;          s countSQL=" SELECT Count(*) as records FROM model.person " if ( search ) s countSQL=countSQL_" WHERE "_where s records=0 #dim RS as %SQL.StatementResult s stmt=##class(%SQL.Statement).%New() s sc=stmt.%Prepare(countSQL) if 'sc d ..ShowError(sc) Q $$$OK s RS=stmt.%Execute(params...) if RS.%SQLCODE d ##class(%SYSTEM.SQL).SQLCODE(RS.%SQLCODE) Q $$$OK s:RS.%Next() records=RS.records kill RS #;     s total = records\rows ;  , part=records#rows ; s:part total=total+1 ;       #;   ,       s:page>total page=total ; #;        s end=page*rows, start=end-rows #;       #;    sql order by #;    jqgrid    s order="",sidx=$$$get( "sidx" ), sord=$$$get( "sord" ) #;       if $ListFind( $ListBuild("name","year"), sidx ) { s:sidx="year" sidx="""year""" ;year -    sql s order=sidx _ " "_$CASE( sord, "desc": "desc", : "asc" ) } #;      #;    ,   ID s sql=" SELECT ID From model.person " s:search sql=sql_" WHERE "_where s:order'="" sql=sql_" ORDER BY "_order s sc=stmt.%Prepare(sql) if 'sc d ..ShowError(sc) Q $$$OK s RS=stmt.%Execute(params...) if RS.%SQLCODE d ##class(%SYSTEM.SQL).SQLCODE(RS.%SQLCODE) Q $$$OK write "{" ;    , """records"": ", records ;     , ", ""total"": ", total ;   , ", ""page"": ", page ;    , ", ""rows"": [" ;   #;      #;    JSON - http://json.org #;  ..QuoteJS()   #;-    #define json(%str) """"_$replace($zcvt(%str,"O","JS"),"\'","'")_"""" #;  s sc="" for { s sc=RS.%Next() Quit:sc=0 s rnum=RS.%ROWCOUNT if (rnum < start) continue ;    if (rnum > end) Quit ;    #;    ,   #;rnum>1 -    ,  start=0 if ( rnum > start ) && ( rnum > 1 ) { w "," } s name=##class(model.person).nameGetStored(RS.ID) , year=##class(model.person).yearGetStored(RS.ID) w "{""id"":",RS.ID,",""name"":",$$$json(name),",""year"":",$$$json(year),"}" } w "]}" Q $$$OK } ///    ClassMethod Add() As %Status { s obj=##class(model.person).%New() Q ..Set(.obj) } ///     ClassMethod Edit() As %Status { s id=$$$get("id"), obj=##class(model.person).%OpenId(id,.sc) if $$$ISERR( sc ) { Q ..wResult( sc, id ) } Q ..Set(.obj) } ///  ,  ,   ClassMethod Set(obj As model.person) As %Status { if ( $g(obj) = "" ) || ( '$IsObject(obj) ) { s sc=$$$ERROR( $$$GeneralError, $$$Text("   ") ) Q ..wResult( sc ) } s obj.name=$$$get("name") s obj.year=$$$get("year") s id="", sc=obj.%Save() s:$$$ISOK(sc) id=obj.%Id() Q ..wResult( sc, id ) Q $$$OK } ///   ClassMethod Del() As %Status { s id=$$$get("id"), sc=##class(model.person).%DeleteId(id) Q ..wResult( sc, id ) Q $$$OK } ///   ClassMethod wResult(sc As %String = "", id As %String) As %Status { s result="false", msg="", id=$g(id) if $$$ISOK( $g(sc) ) { s result="true" } else { s msg=##class(%SYSTEM.Status).GetOneErrorText(sc) } w "[",result,",",..QuoteJS(msg),",",..QuoteJS(id),"]" Q $$$OK } }
      
      





アプリケーションを起動するには、Cache Studioでview.personクラスを開き、F5を押します。 ここに実際の例がデプロイされています。



塩と砂糖を味わう



例は、比較的単純なタスクを実装するために必要な大量のコードのために衝撃的な印象を与えることができます。 この時点で、Cachéはオブジェクト指向のDBMSであり、このコードのほとんどはパラメータ化して親クラスに配置するか、必要なクラスのセットを作成する対話型ダイアログとして実装できることを覚えておく必要があります。 次に、この例を実装するために必要なパラメーターは、保存されたクラスの名前とそのプロパティのリストの2つだけです。



UPD: jqueryui.comがデザインと構造を変更し、accessからthemeswitchertool.jsを削除したのは、記事の公開日でした。



All Articles