يجب أن تكون قوائم السمات مألوفة للجميع. عادةً ما تكون قائمة السمات التي يتم إنشاؤها باستخدام HTML5 عبارة عن قائمة منسدلة، وفي كثير من الحالات، لا تكون القائمة المنسدلة كافية. لقد حاولت استخدام HT للويب لتحقيق وظيفة النقر فوق الزر في شريط الخصائص لإظهار مربع اختيار متعدد الوظائف وتحديد البيانات الواردة، وأشعر أن الممارسة العامة بسيطة ومريحة نسبيًا، لذا سأشاركها معك هنا.
الاداءاتhttp://www.hightopo.com/demo/propertyEditor/index.html
تنفيذ التعليمات البرمجية خريطة الطوبولوجيامن العرض أعلاه، يمكننا أن نرى أن الصفحة بأكملها مقسمة إلى 3 أجزاء، جزء طوبولوجيا graphView على اليسار، وجزء جدول tableView في الزاوية اليمنى السفلية، وجزء سمة propertyView في الزاوية اليمنى العليا. نقوم أولًا بتقسيم المشهد بأكمله، ومن ثم إضافة محتوى محدد لكل جزء:
gv = new ht.graph.GraphView();var tablePane = new ht.widget.TablePane(gv.dm());// مكون لوحة الجدول propertyView = new ht.widget.PropertyView(gv.dm());/ /formPane موجود في propertyView، لذا يجب عليك أولاً تحديد var rightView = new ht.widget.SplitView(propertyView, tablePane, 'v', 0.4);// قم بتقسيم المكون، حيث يتم تقسيم v إلى طبقات علوية وسفلية، وتكون النسبة 0.4:0.6rightView.getView().style.borderLeft = '1px Solid #000';var borderPane = new ht .widget.BorderPane( );// مكون لوحة الحدود borderPane.setRightView(rightView, 400);// تعيين borderPane المكون الصحيح هو rightView بعرض 400borderPane.setCenterView(gv);// قم بتعيين المكون الأوسط borderPane على gv borderPane.addToDOM();// أضف مكون borderPane إلى النص
الأجزاء الجديدة في الكود أعلاه عبارة عن مكونات مغلفة بـ HT، وهي تعادل الفئات. فيما يلي شرح لمكون تقسيم SplitView - يمكن أن تكون المكونات مكونات يوفرها إطار عمل HT، أو يمكن أن تكون مكونًا أصليًا لـ HTML. يتم وضع المكون الفرعي بشكل مطلق مع الموضع المطلق المكون السفلي، h يعني تقسيم اليسار واليمين v يشير إلى التقسيم العلوي والسفلي. القيمة الافتراضية لموضع التقسيم هي 0.5 إذا كانت قيمة الإعداد هي 0~1، فسيتم تقسيمها بنسبة مئوية أكبر من 1 يمثل العرض أو الارتفاع المطلق للمكون الأيسر أو المكون العلوي. يمثل أقل من 1 العرض أو الارتفاع المطلق للمكون الأيمن أو المكون السفلي)؛ ومكون لوحة BorderPane عبارة عن حاوية تخطيط، يمكنها وضع المكونات الفرعية في خمس مناطق: الأعلى والأسفل واليسار واليمين والوسط. يمكن أن تكون المكونات الفرعية عبارة عن مكونات مقدمة من إطار عمل HT، أو يمكن أن تكون مكونات HTML أصلية أداء تحديد المواقع المطلق للوضع المطلق. أقوم هنا بدمج SplitView وBorderPane لتقسيم المشهد إلى ثلاثة أجزاء. أخيرًا، تذكر إضافة حاوية التخطيط النهائية إلى النص أو أي علامة HTML حتى يمكن عرضها على الواجهة. تعريف addToDOM هو كما يلي:
addToDOM = function(){ var self = this, view = self.getView(), // احصل على القسم الأساسي لهذا المكون style = view.style; // احصل على سمة النمط للقسم الأساسي document.body.appendChild( view) // أضف القسم الأساسي إلى الجسم style.left = '0'; // يحدد HT المكونات لتحديد الموضع المطلق، لذلك يجب تعيين الموضع style.right = '0'; أعلى = '0'؛ style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false });
يتم تضمين مكونات HT بشكل عام في حاويات مثل BorderPane وSplitView وTabView. ويتطلب مكون HT الخارجي من المستخدم إضافة عنصر div الأساسي الذي تم إرجاعه بواسطة getView() يدويًا إلى عنصر DOM الخاص بالصفحة ، عندما يتغير حجم الحاوية الأصلية، إذا كانت الحاوية الأصلية عبارة عن مكونات حاوية محددة مسبقًا لـ HT، مثل BorderPane وSplitView، فستقوم حاوية HT تلقائيًا باستدعاء وظيفة الإبطال للمكون الفرعي بشكل متكرر لإعلام التحديث. ولكن إذا كانت الحاوية الأصلية عبارة عن عنصر html أصلي، فلا يمكن لمكون HT معرفة أنه يحتاج إلى التحديث، لذلك يحتاج مكون HT الأبعد عمومًا إلى الاستماع إلى حدث تغيير حجم النافذة الخاص بالنافذة واستدعاء وظيفة الإبطال للأبعد. المكون للتحديث.
يتم إنشاء المشهد. من أجل إظهار الاختلافات في السمات المقابلة للعقد المختلفة، أضفنا سبع عقد إلى خريطة الطوبولوجيا:
function initModel(){ var name = devices; var count = 0; var root = createNode(name + count++, name + (++count));// المعلمة 1 هي الاسم، المعلمة 2 هي العلامة root.setImage('. /symbols/computerroom/server.json'); root.setName('server'); gv.sm().ss(root);// يتم تحديد العقدة الجذرية بشكل افتراضي for (var i = 0; i < 2; i++) { var iNode = createNode(name + count++, name + (++count) );/ / المعلمة 1 هي الاسم، والمعلمة 2 هي العلامة createEdge(root, iNode); for (var j = 0; j < 2; j++) { var jNode = createNode(name + count++, name + (++count)); createEdge(iNode, jNode } }});
إعلان وظيفة createNode هو كما يلي:
function createNode(name, tag){// إنشاء عقدة flag++; varnode = new ht.Node();node.setName(name); / XX subsystem.json'); false)؛// السمات المخصصة، يمكنك التحكم في العقدة.a('مخفي') للتحكم في رؤية العقد.node.a('Interface type', 'SATA'); ') ; if(flag % 2 === 0){node.a('interface type', 'IDE'); الموقف '، 11)؛ gv.dm().add(node);// أضف العقد إلى حاوية البيانات DataModelNode.tablePane1 = createTableView(serviceType, dataModel1);//إنشاء لوحة جدولNode.tablePane2 = createTableView(serviceSize, dataModel2); tablePane3 = createTableView(version, dataModel3); createFormPane(node.tablePane1);// أنشئ لوحة نموذج العقدة.formPane1.title = 'Type';// للتحضير لعنوان مربع الحوار التاليNode.formPane2 = createFormPane(node.tablePane2); title = 'Memory'; if(flag % 3 === 0){node.formPane3.v('tag', 'Lenovo Server X3650M5 8871'); }else{node.formPane3.v('tag', 'Lenovo IBM X3250 5458I21'); } العقدة.a('model', العقدة.formPane3.v('tag'));
نحن نتحكم في رؤية العقدة من خلال التحكم في السمة المخفية لهذه العقدة واستخدام وظيفة التصفية المرئية setVisibleFunc في graphView:
gv.setVisibleFunc(function(data){ if(data.a('hidden')){ return false; } return true;});لوحة الخصائص
مع العقد، من الطبيعي عرض السمات، جنبًا إلى جنب مع القيم الموجودة في لوحة جدول tablePane أدناه، تتم إضافة إجمالي سبع سمات:
وظيفة createProperty(){// إنشاء خصائص propertyView.addProperties([ { name: 'name',// احصل على سمة الاسم، جنبًا إلى جنب مع سمة accessType لتحقيق الوصول أخيرًا إلى سمات العقدة. القيمة الافتراضية لـ accessType خالية، مثل نظرًا لأن الاسم هو العمر، استخدم طريقة get/set أو is/set الخاصة بـ getAge() وsetAge(98) للوصول (الاسم هنا هو الاسم، لذا احصل عليه من خلال getName()) اسم العرض: 'Name'// قم بتعيين قيمة نص العرض لاسم السمة}, { name: 'hidden',// احصل على السمة المخفية DisplayName: 'Hide this العقدة'، accessType: 'attr'،// إذا كان الاسم مخفيًا، استخدم getAttr( 'hidden') وsetAttr('hidden', false) للوصول إلى الرمز: 'images/alert.gif'، // قم بتعيين نوع قيمة الرمز المعروض على الجانب الأيسر من اسم السمة: 'boolean', // يُستخدم لمطالبة المكون بتوفير عارض مناسب يعرض النوع المنطقي، ويتم عرضه كمربع اختيار قابل للتحرير: صحيح // تعيين ما إذا كانت الخاصية قابلة للتحرير}, { name: 'grade', DisplayName: 'Type' ، accessType : 'attr'، drawPropertyValue: function(g, property, value,rowIndex, x, y, w, h, data, view){// وظيفة عرض قيمة السمة المخصصة var cb = function(v) { data.a('grade', v); } return fillFormPane(data.formPane1, w, h, data.tablePane1,serviceType, cb); 'attr', drawPropertyValue: function(g, property, value,rowIndex, x, y, w, h, data, view){ var cb = function(v) { data.a('number', v); : 'نوع الواجهة' }، { الاسم: 'بطاقة الرسومات'، نوع الوصول: 'attr'، اسم العرض: 'بطاقة الرسومات' }، { الاسم: 'الطراز'، نوع الوصول: 'attr'، اسم العرض: 'النموذج'، } ]);}
القيمة المرجعة للسمة drawPropertyValue في السمتين الثالثة والرابعة هي وظيفة fillFormPane. معلمات هذه الوظيفة هي (form مكون formP، عرض مكون النموذج w، ارتفاع مكون النموذج h، انقر فوق الزر الموجود في مكون النموذج لإنشاء الجدول. المكون tableP في المربع المنبثق، محتوى الصفيف موجود في مكون الجدول، تقوم وظيفة cb بتعيين القيمة التي يتم إرجاعها عن طريق النقر المزدوج فوق الصف في مكون الجدول إلى مربع النص ht.widget.TextField في النموذج).
المعلمة الأولى formP هي إنشاء مكون النموذج. إنشاء مكون النموذج هو إنشاء مكون نموذج وإضافة مربع نص وزر إلى مكون النموذج. هذه الخطوة أيضًا بسيطة جدًا في HT:
وظيفة createFormPane(tPane) {// إنشاء لوحة نموذج var formPane = new ht.widget.FormPane();formPane.setPadding(0);// تعيين التباعد حول النموذج ومحتوى المكون var tField = new ht.widget.TextField();// إنشاء مربع نص tField.setText('');// محتوى مربع النص فارغ tField.setDisabled(true);// مربع النص غير قابل للتشغيلformPane.addRow( [// أضف صفًا إلى النموذج { id: 'tag', // يمكن الحصول على سمة التعريف الفريدة من خلال formPane.getItemById(id) وإضافتها إلى عنصر كائن العنصر المقابل: tField// يمكن أن تكون قيمة السمة عبارة عن عناصر HTML أصلية، ومعلومات نصية مرسومة ذاتيًا داخل FormPane، ومكونات HT المضمنة مثل Button وCheckBox وComboBox، وما إلى ذلك.}, { Button: {// بعد تعيين هذه السمة، سوف يقوم HT يتم إنشاؤها تلقائيًا بناءً على قيمة السمة لكائن ht.widget.Button وحفظها في تسمية سمة العنصر:'...',// محتوى النص الموجود على الزر onClicked: function(){// حدث النقر على الزر for(var أنا = 0؛ أنا < tPane.dm().size(); i++){// قم بتعيين tablePane لتحديد القيمة المقابلة لـformPane بشكل افتراضي var data = tPane.dm().getDatas().get(i); 'value' ) ===formPane.v('tag')){ tPane.sm().ss(data); formPane);// ما يتم إرجاعه هو إنشاء مربع حوار يكون محتواه هو لوحة الجدول} } }], [0.5, 0.1]);// قم بتعيين نسبة العرض للعنصر الأول والعنصر الثاني في مكون الجدول . يحتوي مكون الجدول هذا على عنصرين فقط في المجمل، مربع نص وزر، بنسب 0.5 و0.1 على التوالي return formPane;}
تعد عملية إنشاء وظيفة createDialog بسيطة وواضحة أيضًا. يتم تكوين عنوان مربع الحوار وحجمه ومحتواه وما إلى ذلك من خلال طريقة setConfig(config) التي قمت بتمرير مكون جدول tPane إلى createDialog، والذي يتم استخدامه كـ المحتوى المعروض في مربع الحوار:
وظيفة createDialog(tPane){// إنشاء مربع منبثق Dialo.setConfig({ title: gv.sm().ld().getName()++formPane.title,// عنوان محتوى مربع الحوار: tPane, // قم بتعيين محتوى المربع المنبثق مباشرة على عرض لوحة الجدول: 400، // حدد عرض ارتفاع مربع الحوار: 200، قابل للسحب: صحيح، // حدد ما إذا كان يمكن سحب مربع الحوار وتعديله. قابل للإغلاق: صحيح، // يشير إلى ما إذا كان سيتم عرض زر الإغلاق إلى الحد الأقصى: صحيح، // يشير إلى ما إذا كان يمكن تكبير مربع الحوار: wh، //. حرك الماوس إلى يمين مربع الحوار يمكن تغيير حجم مربع الحوار في الزاوية السفلية، مما يعني أنه يمكن تعديل العرض والارتفاع بواسطة الأزرار: [//أضف زرين { label: 'Cancel', الإجراء: وظيفة () {حوار. إخفاء () } }، { التسمية: 'موافق'، } ] })؛ مربع حوار.show();//إظهار مربع الحوار}
معلمة الجدول tableP الرابعة ليست شيئًا خاصًا، فهي تقوم فقط بإنشاء مكون نموذج ثم إضافة أعمدة إلى مكون النموذج، والخطوات بسيطة والكود بسيط أيضًا:
وظيفة createTableView(arr, dm){// إنشاء مكون الجدول var tableView = new ht.widget.TableView(dm); tableView.addColumns([// أضف معلومات العمود على دفعات باستخدام معلمات صفيف json{ DisplayName: 'ID', / / احصل على محتوى اسم العمود لرأس الجدول drawCell: function(g, data, Selected, column, x, y, w, h, tableView){// طريقة عرض الخلية المخصصة var id = tableView.getRowIndex(data);// إرجاع فهرس الصف حيث يوجد كائن البيانات ht.Default.drawText(g, 'row' + (id + 1), null, null, x, y, w, h, 'center');// معلمات نص الرسم (كائن فرشاة g، محتوى نص القيمة، خط نص الخط، لون النص الملون، إحداثي x عند بدء الرسم، إحداثي y عند بدء الرسم على y، العرض عند الرسم w، الارتفاع عند الرسم h ، محاذاة المحاذاة الأفقية للنص، المحاذاة الرأسية للنص vAlign) } }, {displayName: 'Name', drawCell: function(g, data, Selected, column, x, y, w, h, tableView){ var id = tableView.getRowIndex(data); var info = arr[id]; ht.Default.drawText(g, info, null, null, x, y, w, 'center' } } ]); }
بعد شرح المعلمات في fillFormPane، دعونا نلقي نظرة على كيفية تعريف هذه الوظيفة بشكل أساسي، الخطوة الأخيرة هي النقر على العنصر الموجود في مكون الجدول tablePane وإرجاع هذا العنصر إلى مربع النص textField في مكون النموذج formPane:
دالة fillFormPane(formP, w, h, tableP, arr, cb){//formpane على اليمين if(formP === unified){ return }formP.setWidth(w); setHGap (0); if(formP.v('tag') === 'غير محدد' ||formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){// رد الاتصال عند النقر المزدوج على صف البيانات في مكون الجدول var v = arr[data.a('index ') ];formP.v('tag', v);// قم بتعيين قيمة عنصر العنصر المقابل وفقًا للمعرف، وهو اختصار لـ setValue، العنصر الذي يحمل معرف العلامة هو مربع النص Diagram.hide(. )؛ لو (cb){cb(v);} // إذا تم تمرير معلمة cb، فاضبط قيمة data.a('number')/data.a('helloName') على قيمة الصف الذي تم النقر عليه نقرًا مزدوجًا في الجدول، أي أنه تم تعيينه للسمات الثالثة والرابعة} tableP.onDataClicked = function(data){// Callback Dialogue.getConfig().buttons[1].action = عند النقر فوق صف البيانات في مكون الجدول function(){// انقر فوق "موافق" لمتابعة العمليات التالية var v = arr[data.a('index')];formP.v('tag', v); { cb(v);} } }; إرجاع formP.getView();}
دالة fillFormPane(formP, w, h, tableP, arr, cb){//formpane على اليمين if(formP === unified){ return }formP.setWidth(w); setHGap (0); if(formP.v('tag') === 'غير محدد' || formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){// رد الاتصال عند النقر المزدوج على صف البيانات في مكون الجدول var v = arr[data.a('index ') ];formP.v('tag', v);// قم بتعيين قيمة عنصر العنصر المقابل وفقًا للمعرف، وهو اختصار لـ setValue، العنصر الذي يحمل معرف العلامة هو مربع النص Diagram.hide(. )؛ لو (cb){cb(v);} // إذا تم تمرير معلمة cb، فاضبط قيمة data.a('number')/data.a('helloName') على قيمة الصف الذي تم النقر عليه نقرًا مزدوجًا في الجدول، أي أنه تم تعيينه للسمات الثالثة والرابعة} tableP.onDataClicked = function(data){// Callback Dialogue.getConfig().buttons[1].action = عند النقر فوق صف البيانات في مكون الجدول function(){// انقر فوق "موافق" لمتابعة العمليات التالية var v = arr[data.a('index')];formP.v('tag', v); { cb(v);} } }; إرجاع formP.getView();}
ينتهي عرض شريط الخصائص في الجزء العلوي الأيمن هنا، ويتم إنشاء لوحة الجدول في الجزء السفلي الأيمن بنفس الطريقة. يمكنك قراءة الكود لفهمه بنفسك.
تخطيط تلقائيأخيرًا، دعونا نتحدث عن ترتيب العقد في الواجهة بأكملها. يوفر مكون التخطيط التلقائي للتخطيط التلقائي في HT أنواعًا متعددة من الخوارزميات لترتيب مواضع العقد تلقائيًا بناءً على العلاقة بين العقد والاتصالات. يُستخدم التخطيط التلقائي غالبًا في المشاهد التي يوجد بها العديد من العناصر الرسومية أو علاقات الاتصال المعقدة، مما يجعل من الصعب سحبها ووضعها يدويًا. أقدم كل طريقة تخطيط من خلال الأزرار. انقر فوق الزر المقابل، وسيتم تخطيط طريقة التخطيط تلقائيًا وفقًا لطريقة التخطيط التي تم تحديدها بواسطة الزر المضغوط:
أولاً، قم بإنشاء مثيل جديد، وقم بتمرير الكائن الذي يحتاج إلى تخطيط تلقائي، والذي يمكن أن يكون DataModel وgraphView وgraph3dView، ثم قم بتعيين طريقة التخطيط الافتراضية:
autoLayout = new ht.layout.AutoLayout(gv);setTimeout(function(){ Layout('towardsouth', true);// لأنه قبل تحميل الصورة، يتم تخطيط التخطيط التلقائي وفقًا للحجم الافتراضي للعقدة} ، 200)؛
ثم قم بإنشاء لوحة نموذج formPane، وأضفها إلى النص، ثم ضعها في الزاوية اليسرى العليا من النص، ولن ألصق كل التعليمات البرمجية، فقط قم بعرض زر التخطيط الأول:
function createDirectionForm(){ var form = new ht.widget.FormPane();form.setWidth(200);// تعيين عرض النموذجform.setHeight(80); document.body.appendChild(form.getView()); form .getView().style.background = '#fff';form.getView().style.boxShadow = '4px 16px 16px rgba(0, 0, 0, 0.1)';// تعيين نمط الظل form.addRow([// يتم إخراج هذا السطر بشكل منفصل كعنوان { element: 'Auto Layout:',//Displayed text}] , [0.1]);// يوجد كائن واحد فقط في المصفوفة، فقط قم بتعيين عرض كائن واحد form.addRow([ { Button: { icon: 'Layout/South Layout.json', onClicked: function(){layout('towardsouth', true); .بعد ذلك أضف الأزرار الستة المتبقية]، [0.1، 0.1، 0.1، 0.1، 0.1، 0.1، 0.1]);// هناك سبعة كائنات في المصفوفة، لذلك يجب تعيين عرض الكائنات السبعة return form;}
هذه هي الأجزاء الأكثر إثارة للاهتمام. شكرًا لكم جميعًا على القراءة، وآمل أن تكون مفيدة لدراستكم. وآمل أيضًا أن يدعم الجميع شبكة VeVb للفنون القتالية.