Question

I've got this approach (generating html files from cshtml).

And Durandal's standard directory structure (nothing special).

On some of my pages (partial one) I have the following (among others) (SubPage1.cshtml (referenced as 'SubPage1.html' in durandal)):

...
<select data-bind="event: { change: doSomething }, value: facilityId">
        <option value="0">Any Facility</option>

        @foreach (var facility in Data.CurrentUserFacilities())
        {
            <option value="@facility.FacilityId" selected="@CertainCondition">@facility.FacilityName</option>
        }
</select>
...

(facilityId is ko.observable() in my ViewModel code)

I fill data dependently on current user's session. That's pretty convenient to do with Razor. In this case I don't need the data from dropdown to be presented in my Durandal's ViewModel (I mean its whole list). However, I do need the dropdown's selected value to be applied to ViewModel (SubPage1.js) from the page (when the page is loaded).

What is the best way (and if there is any) to handle this situation? I surely understand, that ideally I should load the page as a static one (just with Knockout bindings), then do some ajax request to server and then bind the data loaded. But, a) using Razor syntax is much more convenient and clean; b) that involves additional ajax request (and additional server logic).


Another approach I see is to notify the ViewModel about the page is loaded somehow and set (probably, manually via javascript) the facilityId current value. Like <script type='text/javascript'> myViewModelIgetSomehow.facilityId(45); </script>. But that also looks like not the best approach.

Any thoughts on that?


That's actually rather a question how to handle the last mentioned thought (how to pass some values from the page loaded SubPage1.cshtml to ViewModel SubPage1.js) not just how to handle Razor + Durandal ViewModel.

Thank you!

Was it helpful?

Solution

I think your best option would be to create a custom binding for knockout. Here's a simple example:

ko.bindingHandlers["serverCombo"] = {
    init: function (element, valueAccessor) {
        var $element = $(element);

        var options = ko.unwrap(valueAccessor());
        var observableTarget = options.value;

        $element.change(function onElementChanged() {
            var newValue = $element.val();
            observableTarget(newValue);                
        });
    },

    update: function (element, valueAccessor) {
        var $element = $(element);

        var options = ko.unwrap(valueAccessor());
        var observableTarget = options.value;

        $element.val(observableTarget());
    }
}

You could then use that binding as follows:

<select data-bind="serverCombo: { value: facilityId }">
    <option value="1">The Deck</option>
    <option value="2">The Pool</option>
    <option value="3">The Shagpile Carpet and Mirrored Ceiling room</option>
</select>

Here's a fiddle which puts the whole thing together. Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top