Durandal.js 2.0 Set the name of the document in activation mode

In my shell, I configured my routes like this:

router.map([ { route: '', title: 'Search', moduleId: 'viewmodels/search/search' }, { route: 'location/:paramX/:paramY', title: 'Location', moduleId: 'viewmodels/location/location' } ]).buildNavigationModel(); 

I have an activation method:

 activate: function(paramX, paramY) { // TODO: set document title // TODO: do something with input params } 

For the location page, the title of the document is Location | [Name of my application]. I would like this to be done from the parameters obtained in the activation method (paramX, paramY) for my activation method for the location page. How to do it?

+6
source share
3 answers

You can achieve this by overriding the default behavior of the router process to set the header.

The title is always set after the navigation is completed, so the activation method of your view was previously called. Current implementation in Durandal 2.0:

  router.updateDocumentTitle = function(instance, instruction) { if (instruction.config.title) { if (app.title) { document.title = instruction.config.title + " | " + app.title; } else { document.title = instruction.config.title; } } else if (app.title) { document.title = app.title; } }; 

This is called in the completeNavigation method in router.js .

In instance param, you have a ViewModel that you are activating, so a possible solution would be to override the updateDocumentTilte function in shell.js or main.js and use instance to get the values โ€‹โ€‹you want, For example, you can do something like this ( make sure you have an instance of app and router ):

  router.updateDocumentTitle = function (instance, instruction) { if (instance.setTitle) document.title = instance.setTitle(); else if (instruction.config.title) { if (app.title) { document.title = instruction.config.title + " | " + app.title; } else { document.title = instruction.config.title; } } else if (app.title) { document.title = app.title; } }; 

In this code, we check if the instance (current ViewModel) setTitle method, if it does, we get the header that calls the function. Then in our viewmodel we can have something like:

 define(function () { var id; var vm = { activate: function (param) { id = param; return true; }, setTitle: function () { return 'My new Title ' + id; //Or whatever you want to return } }; return vm; }); 

If your viewmodel does not contain this method, it should fall to the current behavior.

+10
source

Here's how I got it:

  activate: function (product, context) { // Update the title router.activeInstruction().config.title = "Buy " + product; ... ... ... ... 

It works, but I don't know if this one supports method.

+3
source

I needed to use observable data for this because the data obtained from this header is loaded by AJAX in the activate method.

So, I put this in the application boot code:

 var originalRouterUpdateDocumentTitle = router.updateDocumentTitle; router.updateDocumentTitle = function (instance, instruction) { if (ko.isObservable(instance.documentTitle)) { instruction.config.title = instance.documentTitle; } return originalRouterUpdateDocumentTitle(instance, instruction); }; 

If the view model has the observable name documentTitle , it is copied to instruction.config.title . It then binds to the actual document.title by Durandal (using a subscription), so whenever the value of the observed value of documentTitle changes, document.title changes. An observable documentTitle can be a simple observable or a computed observable.

This approach also delegates most of the work to the actual router.updateDocumentTitle() method, intercepting and modifying the instruction value based on instance , and then moving on to originalRouterUpdateDocumentTitle .

This works with Durandal 2.1.0.

0
source

Source: https://habr.com/ru/post/953546/


All Articles