2015-10-14 41 views
1

我在尋找的是一種實現模板的方式,其中模板只知道視圖模型的一個接口。有沒有辦法將模板與模型完全分離並完全查看模型?

假設我有一個叫Greetings的視圖。它知道它可以與名爲IGreetingsVM的接口進行通信。

的IGreetingsVM可以看起來像:

interface IGreetingsVM { 
    greetings: KnockoutObservable<string>; 
} 

在實際的視圖模型我實現的接口:

class GreetingsVMImpl implements IGreetingsVM { 
    greetings: KnockoutObservable<string>; 

    constructor() { 
     this.greetings("Hello world"); 
    } 
} 

因爲模板知道它有一個IGreetingsVM,它也知道它可以致電問候語,如下:

<p data-bind="text: greetings"></p> 

這樣,我就可以把整個視圖fr om實際視圖模型實現。

但是,在我見過的大多數例子中,他們通常都會說這個模板必須有這個視圖模型的實現。

這可以在示例Java中實現,其中對於您創建的每個表單都有一個代碼背後的代碼,您可以在其中獲得視圖模型的獲取和設置方法。

實施例:

public class Greeter extends JPanel { 
    public static final string PROP_VIEWMODEL = "viewModel"; 

    private IGreetingsVM viewModel; 
    private JLabel greetingLabel; 
    private BindingGroup bindingGroup; 

    public Greeter() { 
     initComponents(); 
    } 

    public void setViewModel(IGreetingsVM viewModel) { 
     IGreetingsVM oldViewModel = this.viewModel; 
     this.viewModel = viewModel; 
     propertyChangeSupport.firePropertyChange(PROP_VIEWMODEL, oldViewModel, viewModel); 
    } 

    public IGreetingsVM getViewModel() { 
     return this.viewModel; 
    } 

    private void initComponents() { 
     bindingGroup = new BindingGroup(); 

     greetingLabel = new JLabel(); 

     Binding binding = Bindings.createAutoBinding(
      AutoBinding.UpdateStrategy.READ_WRITE, 
      this, 
      ELProperty.create("${viewModel.greetings}"), 
      greetingLabel, 
      BeanProperty.create("text")); 

     // similar to knockout where bindings auto update components. 
     bindingGroup.addBinding(binding); 
    } 
} 

有一種方法與敲除,以實現^在JavaScript,也許優選?

回答

4

JavaScript比Java更容易鬆散,並且不具有或不需要接口的概念。 (我們可能需要這個概念用於設計目的,我只是說這個語言沒有。)你只需提供一個具有必要屬性的對象。

所以在客戶端JavaScript使用KO,你所要做的就是確保在ViewModel你給KO了一個greetings性質,理想的可觀察到的:

// Three different VMs 
 
var vm1 = { 
 
    greetings: ko.observable("Hello from #1") 
 
}; 
 
var vm2 = { 
 
    greetings: ko.observable("Hello from #2"), 
 
    someOtherThing: ko.observable("Something else") 
 
}; 
 
var vm3 = { 
 
    greetings: ko.observable("Hello from #3"), 
 
    different: ko.observable("And now for something completely different") 
 
}; 
 

 
// Note how neither KO nor JavaScript cares that the models are different: 
 
ko.applyBindings(vm1, document.getElementById("ex1")); 
 
ko.applyBindings(vm2, document.getElementById("ex2")); 
 
ko.applyBindings(vm3, document.getElementById("ex3"));
<!-- Three "instances" of your template: --> 
 
<div id="ex1"> 
 
    <span data-bind="text: greetings"></span> 
 
</div> 
 
<div id="ex2"> 
 
    <span data-bind="text: greetings"></span> 
 
</div> 
 
<div id="ex3"> 
 
    <span data-bind="text: greetings"></span> 
 
</div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

相關問題