mehrandvd
mehrandvd

Reputation: 9116

Using Durandal Composition manually

I have an empty container in my html like:

<div id='workspace-container'></div>

I want to create my model manually and compose it with some view, then inject the result into the #workspace-container using javascript like:

var myViewModel = new ViewModel (param1, param2);
// Doing some actions on myViewModel

// Some MAGIC here:
composition.compose(myViewModel, myView, '#workspace-container');

What is the api to do such magic!?

Update1: In fact I need manual binding for a reason. I want to be able to select what to inject. Something like:

if (condition1) {
    var myViewModel1 = new ViewModel1 (param1, param2);
    composition.compose(myViewModel1, myView1, '#workspace-container');
}
else if (condition2) {
    var myViewModel2 = new ViewModel2 (param1, param2);
    composition.compose(myViewModel2, myView2, '#workspace-container');
}
...

Upvotes: 0

Views: 5237

Answers (3)

Joseph Gabriel
Joseph Gabriel

Reputation: 8520

The way you're describing is possible by creating a property on your main view model that exposes the view model that you are trying to compose. If you don't specify the view manually, the view locator will be used to find the view for the specified view model.

Then the binding looks like this:

//in your view
<div id='workspace-container` data-bind='compose: workspaceContainer'></div>

//in your main view model expose the sub view model property property
var self = this;
this.workspaceContainer = ko.observable();

//later
var v, vm;
if ('condition1') {
    system.acquire("viewModels/viewModelForCondition1").done(function (modelCtor) {
        v = "views/viewModelForCondition1.html";
        vm = new modelCtor(param1, param2);
        self.workspaceContainer({ view: v, model: vm });
    });
} else {
    system.acquire("viewModels/viewModelForCondition2").done(function (modelCtor) {
        v = "views/viewModelForCondition2.html";
        vm = new modelCtor(param1, param2);
        self.workspaceContainer({ view: v, model: vm });
    });
}
...

Couple of notes:

  • the compose binding will recognize or respect subsequent changes to the workspaceContainer property.
  • it is important for your view model module to return a constructor function in order for this to work properly.

See the section Composing Explicit Models and Views in this link for more information: http://durandaljs.com/documentation/Using-Composition/

This code is tested using a pre-release version of Durandal 2.0. If there are issues, let me know, and I'll correct them.

Upvotes: 4

RainerAtSpirit
RainerAtSpirit

Reputation: 3723

Assuming you want Durandal 2.0 handles this take a look at example three of the Composing Explicit Models and Views section at Durandal's composition (http://durandaljs.com/documentation/Using-Composition/)

Changing your html to something along the line should get your started.

<div id="workspace-container" 
     data-bind="compose: { model:myViewModel, view:myView }">
</div>

Upvotes: 0

PW Kad
PW Kad

Reputation: 14995

Take a look at the HTML binding -

http://knockoutjs.com/documentation/html-binding.html

That will allow you to directly create an observable containing HTML mark-up. As always, be sure not to expose your view to HTML Injection.

You will have to get creative if you want to have bindings inside of the HTML, because you will need to bind them after they are visible in the DOM.

Another option could be utilizing the built-in template binding, but it isn't going to provide you with a traditional HTML Injection, but may be more of what you are looking for.

http://knockoutjs.com/documentation/template-binding.html

Upvotes: 0

Related Questions