javascript - 有没有办法用knockout完全分离模板和 View 模型?

标签 javascript knockout.js typescript viewmodel

我正在寻找一种实现模板的方法,其中模板只知道 View 模型的接口(interface)。

假设我有一个名为 Greetings 的 View 。它知道它可以与称为 IGreetingsVM 的接口(interface)进行通信。

IGreetingsVM 看起来像这样:

interface IGreetingsVM {
    greetings: KnockoutObservable<string>;
}

在实际的 View 模型中我实现了接口(interface):

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

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

因为模板知道它有一个 IGreetingsVM,它也知道它可以调用问候语,所以:

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

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

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

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

例子:

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 中实现 ^,也许最好使用 knockout?

最佳答案

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

因此在使用 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>

关于javascript - 有没有办法用knockout完全分离模板和 View 模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33125774/

相关文章:

javascript - 了解 Skrollr 数据值

javascript - knockoutjs javascript 到 CoffeeScript

javascript - 类型 'checked' 上不存在属性 'TElement'

angular - ionic 3 中的组件问题

javascript - 使用 defaultExtension 为 systemjs 配置 Angular2 库

javascript - 来自同步 AJAX 调用的控制台日志数据

javascript - Firebase删除、bolt权限配置

javascript - 当 ng-app 未设置为模块名称时,angular 如何选择根/主模块?

javascript - knockout 选项绑定(bind),嵌套选项值

javascript - 使用 KnockoutJS 的项目选择 MVC View