2

I'm using DurandalJs 2.0 and KnockoutJs. I have two HTML pages, add.html and show.html with their JS files. I want to display both pages as composition in one index.html page. On the left is show.html and displays added records, on the right is add.html which allows users to add records.

My problem is that; show.html page should instantly show or append the record as the user adds a new record. When I add a record, it is updated in the repository.js, but how to refresh only show.html to read new record. I tried router.navigate("#/client/index") but it did not work.

<div>
<div id="global">
    <!-- ko compose: {model: 'viewmodels/client/show', view:'views/client/show'} -->
    <!-- /ko-->
    <div id="main" class="container">

        <!--ko compose: {model: router.activeItem, 
    afterCompose: router.afterCompose,
    transition: 'entrance'} -->
        <!-- /ko-->

    </div>
    <div id="push">
        <!-- ko compose: {model: 'viewmodels/client/add', view:'views/client/add'} -->
        <!-- /ko-->
    </div>
</div>

IRONMAN
  • 168
  • 1
  • 10

1 Answers1

3

I suggest that you use application messaging for this. Durandal provides a publisher/subscriber mechanism to communicate between diferent modules whithin the application.

To use this feature, you need the application module from Durandal in both viewmodels:

 var app = require('durandal/app');

In the add viewmodel you can add the code to send a message with the new client to the subscribers, in this scenario the show viewmodel:

addClient: function(client){
    app.trigger('client:add', client);
}

The string 'client:add' is the identifier of the event and the following argument is the message to send to the subscribers. In your scenario, you want to send the new client.

Your show viewmodel could have the following code in the activate method:

activate: function(){
    var self = this;
    subscription = app.on('client:add').then(function (client) {
        self.clients.push(client); //add client into a ko.observableArray?
    };
}

The on method needs the identifier of the event and returns a promise that can be used to execute the code when the event is triggered. Please note that the method returns a subscription object that we can use in the future to cancel the subscription.

Maybe when this view is deatached of the UI you need to cancel the subscription:

 subscription.off();

You could also use other approaches like sharing the same instance of an observableArray between the viewmodels, for example. However I think application messaging is a good way to communicate and decouple parts of the application.

margabit
  • 2,924
  • 18
  • 24
  • Thanks margabit, It worked! But, it gets added twice to the list. For the second Id is null, but rest data is same as the first. – IRONMAN Oct 31 '13 at 08:07
  • Maybe your activate is being called twice? Or you are not calling `subscription.off()` in the right place? – margabit Oct 31 '13 at 09:00