ACP: JavaScript
-
What is the proper way to use ACP JavaScript?
I'm using plugin ACP Js as link in template for ACP section. And I have found issue, that if I return to the same page, without page refresh, it seems, ACP doesn't unload scripts. -
For me, I put a client script in plugin.json, which properly inserts and reloads that script on every page. In the script, I check for a specific tag such as
<div id="myplugindiv">
Then if it exists, I require() a separate script that has the actual logic. If that script would access data that is admin or user specific, I use socket calls I added to the socket.io/plugins module to verify the viewer is the intended user. -
Can you show your code?
Every time you ajaxify (ACP included), NodeBB will try to load the client side module with the same name as the template, via require.js. It will then execute init().
There is no facility to remove event handlers on page change... not sure if there's is really a good way to do it.
-
Here is a template, I'm talking about: https://github.com/NicolasSiver/nodebb-plugin-ns-awards/blob/a87a53ad14b151fe106d2f64adbbf581296ac55f/public/templates/admin/plugins/awards.tpl
-
@julian - You shouldn't have to remove any event handlers as long as they apply to only elements specific to that page. The garbage collector should handle that (after seeing that the DOM element doesn't exist, the event handlers are removed).
I just include the script in the template. Meh
It would be nice if there was some way in the plugin.json or something to declare only certain locations where scripts or styles should apply, maybe? I'm not exactly sure how difficult it would be to accomplish that...
-
admin/plugins/awards
... this is your template, from what I can tell.So, if you create a new js file with this inside:
define('admin/plugins/awards', function() { var Awards = {}; Awards.init = function() { // Stuff here is run every time the page is loaded }; return Awards; });
There's no need to include the script tag at the bottom of the template
-
@julian said:
There's no need to include the script tag at the bottom of the template
Except for the require call, right?
-
Not even that, NodeBB automatically tries to load a plugin that is associated with that template, and executes
.init();
if there is one.So with that template above, create a client-side js file (of any name) with the module name defined as I have defined in my last post's code block. Then add it to the
scripts
array in yourplugin.json
so it gets minified on NodeBB start, and then it will be automatically called. -
-
Awards.init = function() { require(['my/public/path/myjs']); };
-
@yariplus said:
Awards.init = function() { require(['my/public/path/myjs']); };
That isn't any different from including the script manually, though.
-
Oh, i see the problem. Dang. There has to be another way then just putting everything in nodebb.min.js though, right?
-
Also I have found another problem - It's a development.
Minification is part of nodebb startup. So after every single change in client JS, you should restart NodeBB, It takes time...
Maybe NodeBB could borrow ideas from Wordpress and handle JS includes for particular pages?
I'm OK with single minified script for production. -
@Nicolas there is a grunt thing that only does what is necessary. You should try it out.
-
grunt --verbose
? It will restart nodebb, nothing very special...