2016-12-14 29 views
2

在我的應用我使用的淘汰賽。 我有一組問題,每個問題都有一個類型,它決定了它將被渲染的組件(問題模板,見下文)。淘汰賽,太多的無容器if語句

而我的問題是,它使if語句到頁面中的所有。所以我的頁面只是充滿了if語句(這會使html頁面變大),它們是空的。

HTML示例:

<div data-bind="template: {name: 'questions', foreach: questions }"> 
<!-- ko if: type === "label" --> 
<!-- ko template: { name: 'label_component' } --> 
<div data-bind="visible: show, css: { root : isRoot }" class="root"> 
    <div data-bind="html: text, attr: {id: id}" id="1">Question text</div> 
</div> 
<!-- /ko --> 
<!-- /ko --> 
<!-- ko if: type === "bool" --><!-- /ko --> 
<!-- ko if: type === "multitext" --><!-- /ko --> 
<!-- ko if: type === "text" --><!-- /ko --> 
<!-- ko if: type == "number" --><!-- /ko --> 
<!-- ko if: type === "dropdown" --><!-- /ko --> 
<!-- ko if: type === "date" --><!-- /ko --> 

.............

所以你可以看到有7不必要的,如果呈現1所組成的語句。

我的模板:

<div data-bind="template: {name: 'questions', foreach: questions }"></div> 

<script id="questions" type="html/text"> 
    <!-- ko if: type === "label" --> 
    <!-- ko template: { name: 'label_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type === "bool" --> 
    <!-- ko template: { name: 'radio_btn_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type === "multitext" --> 
    <!-- ko template: { name: 'multi_text_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type === "text" --> 
    <!-- ko template: { name: 'text_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type == "number" --> 
    <!-- ko template: { name: 'numeric_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type === "dropdown" --> 
    <!-- ko template: { name: 'dropdown_component' } --><!-- /ko --> 
    <!-- /ko --> 
    <!-- ko if: type === "date" --> 
    <!-- ko template: { name: 'date_component' } --><!-- /ko --> 
    <!-- /ko --> 
</script> 

所以我的問題: 有沒有解決這個辦法嗎?我能以某種方式停止將那些未使用的if語句渲染到頁面中嗎?

謝謝大家的任何想法

+0

一種方式可能是在您的視圖模型來創建你的HTML,並使用類似的東西'html'結合來呈現所需的模板...... – gkb

+0

你能指出我的任何代碼示例嗎?我不完全確定你的意思。 @gkb – xszaboj

+0

看看這裏的html綁定http://knockoutjs.com/documentation/html-binding.html。你可以看到這個例子是如何使用'data-bind =「html:details」'將'viewModel.details'(包含html標記)綁定到html的。所以你可以構建你需要渲染的任何模板(基於'type'),將該標記作爲一個字符串分配給observable並在'html'綁定中使用它。但是,這不會讓你免於寫if -else'子句,但肯定會擺脫那些容器少'if's – gkb

回答

3

所以感謝@gkb,我看它從不同的角度,並提出這一解決方案。

<div data-bind="template: {name: 'questions', foreach: questions }"></div> 

<script id="questions" type="html/text"> 
    <!-- ko template: { name: componentName() } --><!-- /ko --> 
</script> 

和組件名是我的視圖模型的函數:

question.componentName = function() { 

     switch (question.type) { 
      case "label": 
       return "label_component"; 
      case "bool": 
       return "radio_btn_component"; 
      case "multitext": 
       return "multi_text_component"; 
      case "text": 
       return "text_component"; 
      case "number": 
       return "numeric_component"; 
      case "dropdown": 
       return "dropdown_component"; 
      case "date": 
       return "date_component"; 
     } 
     return "label_component"; 
    } 

如果您有任何其他的想法如何可以實現。請告訴我。

+2

我以前用過這種方法 - 沒關係。讓它變得更加平滑的一種方法是「按照慣例」命名一切,所以你可以直接從'question.type'建立模板名稱,所以你不需要'switch'來選擇正確的模板名稱 - 如果你稍後再添加更多類型/組件,這是更新的地方。你幾乎已經有了 - 只有'bool','multitext'和'number'有一個「不同的」模板名稱。 –

+0

很高興看到你想通了.. :-) – gkb