Question

Disclaimer I am working on an edge case here. The Javascript file is dynamically created server-side, and the JSLinks all point to the same absolute URL (receiving different content). JSLink Absolute URLs are only possible on Office365/SharePoint Online


I have a View with CSR file

window.a='a';
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
  var b='b';
  function init() {
    var c='c';
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
      OnPostRender: function(ctx) { 
        try{
            console.log('OnPostRender',window.a,b,c);
            console.log(_spPageContextInfo.serverRequestPath);
        }catch(e){
            console.error(e);
        }
      },
      ListTemplateType: 101
    });
  }
  RegisterModuleInit(SPClientTemplates.Utility.ReplaceUrlTokens("~siteCollection/Style Library/csr.js"), init);
  init();
});
  • When I open this page all is fine
  • When I browse to another page (remember MDS is enabled)
  • And then return to the View
  • ... my globals are gone ... (a is undefined in the second OnPostRender)

everything I defined as global is gone.

If I define b as window.b its destroyed as well.

Now this is a pain because I used JSLink to load a suporting library.. in the global scope.

Note #1

Global functions are not destroyed (all the CSR examples out there are based on functions)

Note #2

Yes, there is

Problem I have: My JS file is dynamically created by a PHP script (and also used by non-SharePoint sites), so it has the same filename but different content

But, after a sleepless night, I am getting there...

Was it helpful?

Solution

I don't think this is necessarily an edge case because it is easy to reproduce the issue and as it turns out, the behaviour is expected.

It might be helpful if you have an on-prem version of SP13 available so you can step through the code in start.debug.js to see what's going on.

I noticed your reference to Hugh Wood's excellent blog post Part 4 - Async Delta Manager but I found the clue in Part 3 - Minimal Download Strategy

Here's a screenshot of part of that post

Screenshot

So with this information I set my SharePoint web app to use the debug versions of the js files, opened up start.debug.js, and this is what I found.

enter image description here

You'll notice on line 2979 that a loop is entered that loops through each member of the window object, checks whether it is a function, undefined, contained in an array called _snapshot, or a namespace.

If none of those conditions are satisfied, on line 2989 the member is set to undefined and deleted (I set a conditional breakpoint on memberIdx=='a' in order to watch your window.a variable be blown away)

So, that explains how your global is disappearing, I guess the next step is to work out how to "register" your global into the _snapshot array so that it is skipped over during this cleanup process.

UPDATE

So the AsyncDeltaManager._snapShot array is populated in start.js on lines 2170, where a copy of each global variable name is saved to the array. This snapshot of the globals is taken only once, the first time the MDS delta is retrieved. If your own global is not declared and populated by then, it looks like it misses out!

enter image description here

SOLUTION

The supported workaround would simply be to store your globals on a namespace, where they won't get get blown away.

Type.registerNamespace("Foo");
Foo.a='a';

SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
  var b='b';
  function init() {
  var c='c';
  SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
    OnPostRender: function(ctx) { 
      try{
          console.log('OnPostRender',Foo.a,b,c);
          console.log(_spPageContextInfo.serverRequestPath);
      }catch(e){
          console.error(e);
      }
    },
    ListTemplateType: 101
  });
}
RegisterModuleInit(SPClientTemplates.Utility.ReplaceUrlTokens("~siteCollection/Style Library/csr.js"), init);
init();
});

Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top