1

I have a view model in a ASP.Net application set up right now to handle some data binding and it interacts with a Razor template on my main view that is shared across several pages. I have a select box in the Razor template that has a data binding on my current view model, but I would have to duplicate this code across several view models to gain the same functionality and I want to just have this part of my view model be abstracted just like my template is an abstraction of the part of the view it is on. Ideally what I want is something like the following (psuedo-code):

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

       }
}

I am a bit new to the MVVM architecture and I'm not exactly sure how to do this with knockout. Can someone help me out?

4

1 回答 1

3

我不确定这是否是您要问的,但听起来您正在寻找使用 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>
于 2013-06-11T21:10:57.060 回答