Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

durandal : best way to pass data between ViewModels

Durandal: What is the correct way to pass data (parameters) between Viewmodels if possible (without dealing with the backend ).

let say i have 2 views overview and details i want that went the user klick on a list element from overview it takes the id of that element and pass it to details Viewmodel so that i can start working with that id.

thank you for the help

like image 294
Gildas.Tambo Avatar asked Feb 15 '23 04:02

Gildas.Tambo


1 Answers

Hint: you probably want the route-driven approach. The other one is for the sake of completeness.

Viewmodel-driven approach In general I would say: create a module, let's call it data, and inject the data module in both viewmodels. Overview can then set the clickedElementId attribute on the data module, and details can read the attribute's value and use it (you could even make the attribute observable so details gets notified when the attribute is changed by overview). This approach works when both viewmodels can be active at the same time, while my next (preferred) solution only works if you route from one view to the other, so they are never active at the same time. This 'viewmodel-driven' approach is something I personally use for common data in the application (you can also use your application shell viewmodel for these kinds of attributes).

Route-driven approach Seems to be what you would want to do given your description of the situation. Defined routes can take (optional) parameters. Suppose you now have route 'details', you can change it to 'details/:id' (accepts an id parameter, non-optional) or 'details(/:id)' (accepts an id parameter, optional).

You need an event handler a bit like this for clicking a list element:

overview.onElementClick = function (e) {
    var element = this, // The idea is that you need the clicked element for the next line of code
        koDataForElement = ko.dataFor(element);

    router.navigate('details/' + koDataForElement.id);
}

ko.dataFor is a nice knockout helper to get the viewmodel data that is bound to the element you pass into it, in this case your list element. On click you want to navigate to details, and pass the id of the clicked element to details. That above code does all that.

Now your details viewmodel's activate function should look like this:

details.activate = function (id) {
    // id is the parameter we defined for the route. Now you are free to leverage it inside your second view!
};

Edit: Additional hint: you can also trigger the route with id directly from a link. Suppose your whole list element is wrapped in an anchor tag, you could do something like this:

<div data-bind="foreach: myListOfElements">
    <a href="#" data-bind="attr: { href: '#details/' + id }">listElementGoesHere</a>
</div>

Good luck! If it's still unclear let me know,

like image 183
Hans Roerdinkholder Avatar answered Feb 24 '23 06:02

Hans Roerdinkholder