【问题标题】:Multiple Independent View Models Interacting (Knockout)多个独立视图模型交互(淘汰赛)
【发布时间】:2013-06-07 20:04:48
【问题描述】:

我现在在 ASP.Net 应用程序中设置了一个视图模型来处理一些数据绑定,它与我的主视图上的 Razor 模板交互,该模板在多个页面之间共享。我在 Razor 模板中有一个选择框,它在我当前的视图模型上有一个数据绑定,但是我必须在多个视图模型中复制这段代码才能获得相同的功能,我只想让我的视图模型的这一部分成为就像我的模板一样抽象是它所在的视图部分的抽象。理想情况下,我想要的是以下内容(伪代码):

class ViewModel1{
       function doSomeAjaxStuff(option from select){

       }

      function doSomethingOnSelectorChange(option from select){
           call doSomeAjaxStuff(option from select);

      }
}

class SelectorViewModel{
       function getSelectorValuesFromAjax(){
          //this function will populate the selectors values from an ajax call
       }

       function sendMessageThatSelectorHasChanged(){
           //this will send to the first viewmodel that the selector value has changed

       }
}

我对 MVVM 架构有点陌生,我不确定如何通过淘汰赛来做到这一点。有人可以帮帮我吗?

【问题讨论】:

  • 是的,我正在使用 TypeScript,谢谢 :)

标签: asp.net mvvm knockout.js typescript


【解决方案1】:

我不确定这是否是您要问的,但听起来您正在寻找使用 Knockout 实现类似可重用控件的东西。我们目前采用的一种方法是将自定义绑定处理程序与模板脚本结合使用。例如,给定一些模板:

<script type="text/html" id="selector-template">
    <!-- ko if: isLoading -->
    Loading data...
    <!-- /ko -->
    <!-- ko ifnot: isLoading -->
    <ul data-bind="foreach: items">
        <li data-bind="
            css: { selected: $parent.selectedItem == $data }, 
            template: $parent.itemTemplate, 
            click: selectItem">
        </li>
    </ul>
    <!-- /ko -->
</script>

...和一个绑定处理程序:

ko.bindingHandlers.selector = {
    init: function(element, valuesAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var bindingValues = valuesAccessor();

        var templateElem = document.createElement('div');
        templateElem.setAttribute('data-bind', 'template: "selector-template"');
        element.appendChild(templateElem);

        var viewModelForControl = new SelectorViewModel(bindingValues);
        var childBindingContext = bindingContext.createChildContext(viewModelForControl);
        ko.applyBindingsToDescendants(childBindingContext, element);
        return { controlsDescendantBindings: true };
    }
};

...您可以像这样实例化自定义控件:

<div data-bind="selector: { 
    itemsUrl: urlForItems, 
    selected: doSomethingOnSelectorChange,
    itemTemplate: 'product-list-item-template'
}"></div>

<script type="text/html" id="product-list-item-template">
    <img data-bind="attr: { src: imageUrl }" />
    <span data-bind="text: description"></span>
</script>

【讨论】:

  • 这是一个很好的答案,我们最终稍微改变了我们的架构,所以问题在一天结束时并不完全一样,但感谢您的帮助!
猜你喜欢
  • 2016-01-27
  • 1970-01-01
  • 2012-11-29
  • 2011-12-21
  • 2013-05-31
  • 2020-12-19
  • 1970-01-01
  • 2018-06-25
  • 2015-04-23
相关资源
最近更新 更多