Question

I'm attempting to create a view that contains a dynamic set of widgets (not actual durandal widgets) within it. Each widget is just a standard module that will have its own behavior and rendering, and the user should be able to drag and reorganize them as well as add additional ones or remove them.

The current file structure is the following:

  • viewmodels
    • home.js
    • widgetA.js
    • widgetB.js
  • views
    • home.html
    • widgetA.html
    • widgetB.html

The home viewModel contains an observableArray, called widgets, which contains the name of the viewmodel of the widget as a string:

   var vm = {
        activate: activate,
        someContext: ko.observable()
        widgets: ko.observableArray()
    };

Problem #1:

If I use a compose binding within a foreach, everything works as expected, for example:

<div data-bind="foreach: widgets">
    <div data-bind="compose: $data"></div>
</div>

However, if I change from foreach to sortable it seems $data doesn't reference the widget anymore, and the current home container view gets rendered infinite times.

UPDATE: In order to see if $data was indeed changing I did the following:

<div data-bind="foreach: widgets">
    <div data-bind="text: JSON.stringify($data)"></div>
</div>

And indeed when using foreach the result was the widget's viewModel name, but when sortable was used, it contained the actual viewModel for the home.

Problem #2:

I'm going to need to send the someContext viewModel property to the widget, since it needs that information for initialization. I have tried using activationData but the error message stated that the object was undefined:

<div data-bind="foreach: widgets">
    <div data-bind="compose: { model: $data, activationData: someContext }"></div>
</div>

I was hoping to avoid having to specifically declare the dependency to every widget type and instantiate them in the home viewModel, by taking advantage of composition in this way, however I might be wrong trying this route.

I based the approach on comments found on this thread: https://groups.google.com/forum/#!topic/durandaljs/it3q3QePI2M

I'm pretty new to knockout+durandal, so all input is greatly appreciated.

Was it helpful?

Solution

Actually I just found out it was an embarrassing mistake on my part. I forgot to include jqueryUI and knockout-sortable in the js bundle. When those components are missing it causes that odd behavior.

I'm leaving the answer here in case it's useful to somebody else.

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