今日、非常に多くのjavascriptフレームワークがあり、それらの多くのために山ほどのドキュメントが書かれています。 不明な理由により、ロシアの開発者にはあまり人気がないフレームワークについて詳しく説明します。
フレームワークはqooxdooと呼ばれます。 「kuksdu」と発音します(英語の書き起こしを好む人:['kuksdu:])。
このフレームワークについて書くためにHabréでいくつかの試みがありましたが、それらはすべて、新しいバージョンのリリースに関するニュースまたは「あなたが書いたフレームワークを見る」などの記事のいくつかの段落に要約されました。 私は数年前からqooxdooに取り組んできましたが、このギャップを埋めたいと思います。
どんな動物で、どんな動物と一緒に食べられるかについて簡単に説明します。 何よりも、フレームワークはExtJSに似ています。 この場合、「類似」という言葉は完全に正しいわけではありませんが、より適切なものを選択することは困難です。 プロジェクト開発は、
1&1 Internet AGの腸で始まりました。 最初のパブリックバージョン0.1は2005年にリリースされました。 現在の現行バージョン4.1。それについて説明します。 いくつかの点から、私は開発者が頭脳を作成するときにQtに触発されたと言うことができます。 開発者の最初の主なアイデアは、人々にHTML、CSS、およびDOMモデルの知識なしでWebアプリケーションを開発する機会を与えることです。 qooxdooを使用できます。 たとえば、単一ページアプリケーション(以下、SPAと呼びます)の形で管理者を書く必要があり、単一のHTMLタグを知らないが、CSSを聞いたことがない初心者は、実際にこれを行うことができます。 これは、HTML、CSS、およびDOMモデルの知識が突然突然不要になるという意味ではありません。 単純に、最初は、それらなしで実行できます。 たとえば、特に興味深いのは、Web上で何かをする必要があるデスクトップアプリケーションの開発者です。
記事の最後に、役に立つリンクがいくつかあります。 特に、
本番環境でのフレームワークの
実際の使用のさまざまな
デモと例へのリンクがあります。
このようなフレームワークについて話すのは退屈で面白くないです。 さらに、開発者はすでにこれを行っています。 したがって、フレームワークの機能を示すために簡単な例を作成することにしました。 多くの人が
http://todomvc.com/プロジェクトについて知っています。 そのため、qooxdooを使用して可能な限り類似したことを行います。 公平を期して、開発者はすでに
todoシートのデモを行っていますが、これは必要なものではありません。
それでは始めましょう。
SPA(qooxdoo用語のデスクトップ)が考慮されることに注意してください。 まず、qooxdoo sdkをダウンロードする必要があります。
このリンクでこれを行うことができます。 SDKには、アプリケーションテンプレートの生成、デバッグバージョンとリリースバージョンの収集、自動ドキュメント、tutusなどの収集を可能にする多数のユーティリティが含まれています。
こちらからツールチェーンのドキュメントを読むことができ
ます 。
アプリケーションテンプレートを作成するには、次を実行します。
create-application.py --name=todos
この操作の後、次のアプリケーションフレームワークを取得します。

アプリケーションは空では生成されません。 アラートが表示されるボタンをクリックすると、ボタンが表示されます。
メインのApplication.jsファイルには、次のコードが含まれます。
qx.Class.define("todos.Application", { extend : qx.application.Standalone, members : { main : function() {
著者のアイデアを見るために、アプリケーションの販売版または製品版を収集する必要があります。
プロジェクトフォルダーに移動して実行すると、最初のオプションが取得されます。
./generate.py source
2番目は開始後に取得できます。
./generate.py build
その後、対応するindex.htmlファイルをブラウザーにロードし、次の図を確認します。

ボタンは押せますが、押せません。
牛を奪うことができます。 ここで、アプリケーションの機能が終了します。 奇跡は起こらなかったので、コードを作成する必要があります。実際にコードを作成します。
せっかちな人のために、すぐに
GitHubへのリンクを提供します。このリンクは、すぐに使える既製のバージョンです。 成功するには、githubからのソースに加えて、SDKをダウンロードし、config.jsonファイルに正しいパス「QOOXDOO_PATH」を設定する必要があります。 次に、上記のように、必要なバージョンを収集する必要があります。
さて、アプリケーションを自然な形で順番に作成するプロセスを検討します。
まず、todoシートのウィンドウウィジェットに空白を作成し、ジェネレーターが生成したすべてをApplication.jsから容赦なく削除します。 以下が得られます。
Window.js
qx.Class.define("todos.Window", { extend : qx.ui.window.Window, construct: function(){ this.base(arguments); this.set({ caption: "todos", width: 480, height: 640, allowMinimize: false, allowMaximize: false, allowClose: false }); this.addListenerOnce("appear", function(){ this.center(); }, this); } });
Application.js
qx.Class.define("todos.Application", { extend : qx.application.Standalone, members : { main : function() {
組み立て後、この美しさを見ることができます。

それを意味で満たすときです。 次の要素が必要です:ツールバー、todoシートエントリ、およびシートにエントリを追加するための要素。 レコードTodoシートは繰り返し要素であり、個別のウィジェットとして配置します。 ツールバーとレコードをシートに追加するための要素は、個別のウィジェットとして作成できます。これにより、ウィジェットを再利用したり、ウィンドウの一部にしたりできます。 ツールバーを別のウィジェットにし、レコードを追加する要素をWindowの一部として残し、そうすることができることを示します。 上記のすべてを実行し、ウィジェットに命を吹き込みます。
ToDo.js
qx.Class.define("todos.ToDo", { extend: qx.ui.core.Widget, events : { remove : "qx.event.type.Event" }, properties: { completed: { init: false, check: "Boolean", event: "completedChanged" }, appearance: { refine: true, init: "todo" } }, construct: function(text){ this.base(arguments); var grid = new qx.ui.layout.Grid; grid.setColumnWidth(0, 20); grid.setColumnFlex(1, 1); grid.setColumnWidth(2, 20); grid.setColumnAlign(0, "center", "middle"); grid.setColumnAlign(1, "left", "middle"); grid.setColumnAlign(2, "center", "middle"); this._setLayout(grid); this._add(this.getChildControl("checkbox"), {row: 0, column: 0}); this._add(this.getChildControl("text-container"), {row: 0, column: 1}); this._add(this.getChildControl("icon"), {row: 0, column: 2}); this.getChildControl("label").setValue(text); this.addListener("mouseover", function(){this.getChildControl("icon").show();}, this); this.addListener("mouseout", function(){this.getChildControl("icon").hide();}, this); this.getChildControl("icon").hide(); this.getChildControl("text-container").addListener("dblclick", this.__editToDo, this); }, members : {
StatusBar.js
qx.Class.define("todos.StatusBar", { extend: qx.ui.core.Widget, events: { removeCompleted: "qx.event.type.Event" }, properties: { todos: { init: [], check: "Array" }, filter: { init: "all", check: ["all", "active", "completed"], event: "filterChanged" } }, construct: function() { this.base(arguments); var grid = new qx.ui.layout.Grid; grid.setColumnWidth(0, 100); grid.setColumnFlex(1, 1); grid.setColumnWidth(2, 130); grid.setColumnAlign(0, "left", "middle"); grid.setColumnAlign(1, "center", "middle"); grid.setColumnAlign(2, "right", "middle"); grid.setRowHeight(0, 26); this._setLayout(grid); this._add(this.getChildControl("info"), {row: 0, column: 0}); this._add(this.getChildControl("filter"), {row: 0, column: 1}); this._add(this.getChildControl("remove-completed-button"), {row: 0, column: 2}); this.update(); }, destruct: function() { this.__rgFilter.dispose(); }, members : { __rgFilter: null, update: function() { var todosCount = this.getTodos().length; var itemsLeft = this.getTodos().filter(function(item){return !item.getCompleted();}).length; this.getChildControl("info").setValue("<b>"+itemsLeft+"</b> items left"); if (itemsLeft === todosCount) { this.getChildControl("remove-completed-button").exclude(); } else { this.getChildControl("remove-completed-button").setLabel("Clear completed ("+(todosCount-itemsLeft)+")"); this.getChildControl("remove-completed-button").show(); } },
Window.js
qx.Class.define("todos.Window", { extend: qx.ui.window.Window, properties: { appearance: { refine: true, init: "todo-window" }, todos: { init: [], check: "Array", event: "todosChanged" }, filter: { init: "all", check: ["all", "active", "completed"], apply: "__applyFilter" } }, construct: function(){ this.base(arguments); this.set({ caption: "todos", width: 480, height: 640, allowMinimize: false, allowMaximize: false, allowClose: false }); this.setLayout(new qx.ui.layout.VBox(2)); this.add(this.getChildControl("todo-writer")); this.add(this.getChildControl("todos-scroll"), {flex: 1}); this.add(this.getChildControl("statusbar")); this.addListenerOnce("appear", function(){ this.center(); }, this); }, destruct : function() { var todoItems = this.getTodos(); for (var i= 0, l=todoItems.length; i<l; i++) { todoItems[i].dispose(); } }, members : {
この段階で、機能的に完全なアプリケーションが完成しました。 核戦争のように、警告が1つだけあります。

彼をまともな顔にしようとしましょう。 私はすぐに予約をします、私のデザイナーはヤギのバレリーナのようなものですので、私にとっての仕事は、todoシートがフリルなしできれいに見えるように最大限にすることです。
Qooxdooは、アプリケーションの外観を担当します。 フレームワークには4つのテーマがあります。 テーマは拡張、書き換えなどが可能です。 qooxdooのトピックには5つのコンポーネントがあり、次のように定義されます。
qx.Theme.define("todos.theme.Theme", { meta : { color : todos.theme.Color, decoration : todos.theme.Decoration, font : todos.theme.Font, icon : qx.theme.icon.Tango, appearance : todos.theme.Appearance } });
トピックの詳細については、
こちらをご覧ください 。
そのため、次の変更を行います。
Appearance.js
qx.Theme.define("todos.theme.Appearance", { extend : qx.theme.simple.Appearance, appearances : { "todo-window" : { include : "window", alias : "window", style : function(){ return { contentPadding: 0 }; } }, "checkbox": { alias : "atom", style : function(states) { var icon; if (states.checked) { icon = "todos/checked.png"; } else if (states.undetermined) { icon = qx.theme.simple.Image.URLS["todos/undetermined.png"]; } else { icon = qx.theme.simple.Image.URLS["blank"]; } return { icon: icon, gap: 8, cursor: "pointer" } } }, "radiobutton": { style : function(states) { return { icon : null, font : states.checked ? "bold" : "default", textColor : states.checked ? "green" : "black", cursor: "pointer" } } }, "checkbox/icon" : { style : function(states) { return { decorator : "checkbox", width : 16, height : 16, backgroundColor : "white" } } }, "todo-window/checkbox" : "checkbox", "todo-window/textfield" : "textfield", "todo-window/todos-scroll" : "scrollarea", "todo-window/todo-writer" : { style : function() { return { padding : [2, 2, 0, 0] }; } }, "todo-window/statusbar" : { style : function() { return { padding : [ 2, 6], decorator : "statusbar", minHeight : 32, height : 32 }; } }, "todo-window/statusbar/info" : "label", "todo-window/statusbar/rb-filter-all" : "radiobutton", "todo-window/statusbar/rb-filter-active" : "radiobutton", "todo-window/statusbar/rb-filter-completed" : "radiobutton", "todo-window/statusbar/remove-completed-button" : { include : "button", alias : "button", style : function() { return { width : 150, allowGrowX : false }; } }, "todo/label" : { include : "label", alias : "label", style : function(states) { return { font : (states.completed ? "line-through" : "default"), textColor : (states.completed ? "light-gray" : "black"), cursor : "text" }; } }, "todo/icon" : { style : function() { return { cursor : "pointer" }; } }, "todo/text-container" : { style : function() { return { allowGrowY : false }; } }, "todo/checkbox" : "checkbox" } });
Color.js
qx.Theme.define("todos.theme.Color", { extend : qx.theme.simple.Color, colors : { "light-gray" : "#BBBBBB", "border-checkbox": "#B6B6B6" } });
Decoration.js
qx.Theme.define("todos.theme.Decoration", { extend : qx.theme.simple.Decoration, decorations : { "statusbar" : { style : { backgroundColor : "background", width: [2, 0, 0, 0], color : "window-border-inner" } }, "checkbox" : { decorator : [ qx.ui.decoration.MBorderRadius, qx.ui.decoration.MSingleBorder ], style : { radius : 3, width : 1, color : "border-checkbox" } } } });
Font.js
qx.Theme.define("todos.theme.Font", { extend : qx.theme.simple.Font, fonts : { "line-through" : { size : 13, family : ["arial", "sans-serif"], decoration : "line-through" } } });
その後、TODOシートは次のようになります。

これで、今すぐ終了できます。 膨大な数の質問には触れませんでしたが、これは1つの記事の枠組み内では不可能です。 フレームワークを小さなタスクの例として紹介し、できるだけ詳細を掘り下げたくはありませんでした。 詳細については、提供されているリンクをご覧ください。 PMのすべてのエラーとタイプミスについてお書きください。 ご清聴ありがとうございました。
便利なリンク:Qooxdooホームページ:http://qooxdoo.org/
SDKダウンロードページ:
http :
//qooxdoo.org/downloadsさまざまなデモ:
http :
//qooxdoo.org/demos使用例:
http :
//qooxdoo.org/community/real_life_examplesSPAチュートリアル:
http :
//manual.qooxdoo.org/current/pages/desktop/tutorials/tutorial-part-1.htmlGithubサンプルコード:
https :
//github.com/VasisualyLokhankin/todolist_qooxdoo