【问题标题】:Is there a way to seperate templates and view models completely with knockout?有没有办法通过淘汰赛将模板和视图模型完全分开?
【发布时间】:2016-01-12 13:37:35
【问题描述】:

我正在寻找的是一种实现模板的方法,其中模板只知道视图模型的接口。

假设我有一个名为 Greetings 的视图。它知道它可以与一个名为 IGreetingsVM 的接口进行通信。

IGreetingsVM 可能类似于:

interface IGreetingsVM {
    greetings: KnockoutObservable<string>;
}

在实际的视图模型中我实现了接口:

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

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

既然模板知道它有一个IGreetingsVM,它也知道它可以调用greeting,所以:

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

通过这种方式,我可以将整个视图与实际的视图模型实现分开。

但是,在我见过的大多数示例中,他们通常说这个模板必须有这个 viewmodel 实现。

这可以在示例 Java 中实现,其中您为创建的每个表单都有一个代码隐藏文件,您可以在其中为视图模型设置一个 get 和 set 方法。

例子:

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 中实现 ^,最好是通过敲除?

【问题讨论】:

    标签: javascript knockout.js typescript viewmodel


    【解决方案1】:

    JavaScript 比 Java 宽松得多,并且没有或不需要 接口 的概念。 (我们可能出于设计目的需要这个概念,我只是说语言不需要。)您只需提供一个具有必要属性的对象。

    因此,在使用 KO 的客户端 JavaScript 中,您所要做的就是确保您提供给 KO 的 viewModel 具有 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>

    【讨论】:

      猜你喜欢
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 2019-11-14
      • 2013-02-19
      • 1970-01-01
      相关资源
      最近更新 更多