luci-base: ui.js: add instantiateView() helper
authorJo-Philipp Wich <jo@mein.io>
Fri, 3 Apr 2020 11:21:09 +0000 (13:21 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 7 May 2020 17:40:49 +0000 (19:40 +0200)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit d9e9cf92d15c81284000c7c97c6f7bf2b5953c2d)

modules/luci-base/htdocs/luci-static/resources/ui.js
modules/luci-base/luasrc/view/view.htm

index f731a5a81875f88df953b59805d7964cc3d52f9e..cd5f9cd6b97cb09be4e4b7eaf4d1a107a29cba6a 100644 (file)
@@ -4157,6 +4157,38 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
                }, this.varargs(arguments, 2, ctx));
        },
 
+       /**
+        * Load specified view class path and set it up.
+        *
+        * Transforms the given view path into a class name, requires it
+        * using [LuCI.require()]{@link LuCI#require} and asserts that the
+        * resulting class instance is a descendant of
+        * [LuCI.view]{@link LuCI.view}.
+        *
+        * By instantiating the view class, its corresponding contents are
+        * rendered and included into the view area. Any runtime errors are
+        * catched and rendered using [LuCI.error()]{@link LuCI#error}.
+        *
+        * @param {string} path
+        * The view path to render.
+        *
+        * @returns {Promise<LuCI.view>}
+        * Returns a promise resolving to the loaded view instance.
+        */
+       instantiateView: function(path) {
+               var className = 'view.%s'.format(path.replace(/\//g, '.'));
+
+               return L.require(className).then(function(view) {
+                       if (!(view instanceof View))
+                               throw new TypeError('Loaded class %s is not a descendant of View'.format(className));
+
+                       return view;
+               }).catch(function(err) {
+                       dom.content(document.querySelector('#view'), null);
+                       L.error(err);
+               });
+       },
+
        AbstractElement: UIElement,
 
        /* Widgets */
index 9220ecf2992e1803f46e6547f5ef65ce636da8ef..b451e8cfbf9280a63534db65a49c960554a14bcc 100644 (file)
@@ -2,10 +2,11 @@
 
 <div id="view">
        <div class="spinning"><%:Loading view…%></div>
-       <script type="text/javascript">L.require('view.<%=view%>').catch(function(err) {
-               L.dom.content(document.querySelector('#view'), null);
-               L.error(err);
-       });</script>
+       <script type="text/javascript">
+               L.require('ui').then(function(ui) {
+                       ui.instantiateView('<%=view%>');
+               });
+       </script>
 </div>
 
 <%+footer%>