3

的HTML視圖在我的多租戶應用程序,我有以下的很多實例:撰寫與條件邏輯

<!-- ko if: tenantA() --> 
<div>Tenant One snippet</div> 
<!-- /ko --> 
<!-- ko if: tenantB() --> 
<div>Tenant Two snippet</div> 
<!-- /ko --> 
<!-- ko if: userTypeA() --> 
<div>User type A snippet</div> 
<!-- /ko --> 
<!-- ko if: userTypeB() --> 
<div>User type B snippet</div> 
<!-- /ko --> 

這是一個過於簡單的例子,但你得到的圖片 - 大圖的許多元件是由基於從各種數據點的業務邏輯。

這樣做的好處是我有一個視圖,解決方案的佔用空間更易於管理,但有點麻煩。那裏有什麼替代模式?

我正在考慮將條件上顯示的任何內容分解爲一個html模板,並基於js viewmodel中的邏輯呈現html,但這會在我的視圖模型中引入更多複雜性,並混淆我的解決方案佔用空間(這對於我在開發期間快速導航)。

我正在使用杜蘭達爾和淘汰賽,但標記爲Aurelia,因爲我將在某個時間進行遷移,認爲這是一個比特定技術問題更多的模式問題。

+0

是c onditions獨家? –

回答

1

一旦您的應用程序開始變大,HTML模板總是趨於凌亂,難以維護。

我建議你把你的HTML分成多個組件,它會更容易維護,最重要的是你最終會重用所有這些組件。

其中一個最好的例子就是JSX,它可以在JS內部編寫HTML的React.js中使用。所以你可以將你的應用分成可維護的組件。給JSX一個嘗試,它真的讓你的生活更容易,就像字體終端開發者一樣。

+1

在Aurelia會很容易。最佳做法是創建組件(用於模塊化和重用),然後使用'if.bind'屬性將它們包含或不包含在DOM中。 – LStarky

3

邏輯模式,軟件設計概念

你一定要在components方面來思考,不管你選擇使用什麼樣的實現語言或框架。

  1. 劃分應用程序分爲不同的意見(也許爲每個導航菜單元素)。
  2. 根據它們所服務的功能類型,進一步細分這些視圖(根據需要)。我喜歡Bootstrap的面板幫助您可視化的方式。
  3. 開發這些組件中的每一個,併爲它們命名,例如ContactList,ContactEdit,ContactView等。爲這些組件中的每個組件開發HTML視圖和JavaScript,TypeScript或其他語言視圖模型。請務必使用MVC邏輯將視圖與數據分開,並使用視圖中的佔位符指示填寫數據的位置。這些視圖就像模板一樣。
  4. 使用您的特定語言或框架將其鏈接在一起。

這是關於Component-Based Software Architecture and Design的很好的教程。

奧裏利亞組件邏輯

我目前使用Aurelia路上,因爲你提到它,我們將使用奧裏利亞框架作爲一個例子來說明上述原則。最佳做法是創建組件(用於模塊化和重用),然後使用if.bind屬性將它們包含或不包含在DOM中。

例子:

<tenant-one if.bind="tenantA"></tenant-one> 
<tenant-two if.bind="tenantB"></tenant-two> 

或僅顯示/隱藏視圖中的每個組件(但包括所有在DOM),你可以使用show.bind代替if.bind,但似乎做的意義不大您用例。

奧裏利亞數據綁定

因爲我不知道你真正希望在這裏顯示,上面的代碼是基於問題的代碼段。但是,對於只有數據發生更改的類似視圖(如模板),您可以將父數據綁定到子級,以便可以正確顯示數據。在奧裏利亞,這看起來像這樣。

例子:

<tenant-view data.bind="tenantData"></tenant-view> 

更復雜的例子:

<tenant-view fname.bind="firstName" lname.bind="lastName" data.bind="tenantData"></tenant-view> 

在每個例子中,你需要開發4個文件。您需要具有視圖和視圖模型的主(父)容器。視圖模型負責檢索或訪問租戶信息,然後將其傳遞給每個子組件。子組件將擁有自己的視圖和視圖模型。

例如,TenantView視圖(高度簡化的)可能是這樣的:

<template> 
    <p><strong>Tenant Name: </strong>${fname} ${lname}</p> 
    <p><strong>Additional Data: </strong>${data}</p> 
    <p if.bind="data.rentDue">Tenant's rent is due!</p> 
</template> 

然後是TenantView視圖模型(再次,高度簡化的)可能是這樣的:

import { bindable, bindingMode } from 'aurelia-framework'; 

export class TenantView { 
    @bindable fname; 
    @bindable lname; 
    @bindable data; 
} 

一旦您將創建此組件,然後將其插入(可選)父視圖中,如下所示:

<template> 
    <h1>Contact View</h1> 
    <h2>${firstName} ${lastName}</h2> 

    <tenant-view if.bind="cat == 'tenant'" fname.bind="firstName" lname.bind="lastName" data.bind="contactData"></tenant-view> 

    <phone-numbers data.bind="contactData"></phone-numbers> <!-- another component --> 

    <page-footer></page-footer> <!-- another component --> 

</template> 
+0

這很好,但它是一個技術特定的解決方案。我想將它抽象爲「模式定義」類型的答案,因爲我相信這對未來的讀者會更有價值。您正在推薦將視圖組件提取到單獨的文件中,然後將視圖邏輯留在視圖中,對嗎? – SB2055

+0

我唯一的問題是,我有這個數百個實例 - 視圖取決於某些條件。將這些提取到單個文件中將成爲維護的噩夢。 – SB2055

+0

您的觀點應該包含適合各種需求的適當邏輯,而不一定要求每個視圖文件都有不同的視圖文件。如果目的或結構存在顯着差異,則只能顯示不同的視圖文件。我假設你已經知道如何綁定父子屬性。 – LStarky