在混合 Cordova/Android 应用程序的 class 中调用另一个 JavaScript 方法

Calling another JavaScript method in a class in a hybrid Cordova/Android app

我正在整理一个相当大的混合 Cordova/Android 应用程序。我正在做的一件事是减少必须在启动时构建的初始 DOM 树的大小,方法是将不是立即需要的位分割到 "template" 文件夹中,然后我从中加载它们一经请求。为此,我定义了一个 Loader class,如下所示

class Loader
{
 constructor()
 {
  this.prior = null;
  this.current = null;
 }

 loadPageTemplate(page)
 {
  this.prior = this.current;
  this.current = page;   
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){this.pageTemplateLoaded(xhr.responseText);};
  xhr.onerror = function(){alert(`${this.current} failed`);};
  xhr.open('GET',`tpl/${page}.es6`);
  xhr.send(null);
 }

 pageTemplateLoaded(content)
 {
  this.blankPage();
  if (this.prior) delete(this.prior);
  eval(content);
 }

 displayPage(newPage){document.getElementById('page').appendChild(newPage);}

 blankPage()
 {
  let page = document.getElementById('page');
  while (page.firstChild) page.removeChild(page.firstChild);    
 }
}

var _hold = {loader:new Loader()};

我确保加载程序脚本是 Cordova 加载的 index.html 文件的 <head> 部分中最先看到的内容。这是失败的,因为 Cordova 应用程序中的 WebView 会引发类似

的投诉

this.pageTemplateLoaded is not defined.

在以这种方式使用 JavaScript classes 时,我是一个相对初学者,所以我怀疑我在这里做错了什么。

我本来打算删除这个问题,但为了让任何按照类似思路做事的人受益,我决定将其保留在答案中。

这里的关键是了解 Loader class 的确切用途 - 仅用作一些实用功能的便捷存储库。在这种情况下,我们需要做的是将方法定义为静态的,然后通过 Loader 原型引用它们,而无需实例化它。这是我修改后的有效代码

class Loader
{

 static loadPageTemplate(page)
 {
  _hold.prior = _hold.current;   
  _hold.current = page;   
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){Loader.pageTemplateLoaded(xhr.responseText);};
  xhr.onerror = function(){alert(`${_hold.current} failed`);};
  xhr.open('GET',`tpl/${page}.es6`);
  xhr.send(null);
 }

 static pageTemplateLoaded(content)
 {
  Loader.blankPage();
  eval(content);
 }

 static displayPage(newPage){document.getElementById('page').appendChild(newPage);}

 static blankPage()
 {
  let page = document.getElementById('page');
  while (page.firstChild) page.removeChild(page.firstChild); 
  if (_hold.prior) delete(_hold.prior);
 }
}

var _hold = {current:null};

注意事项

  • 通过这种方式,您将无法再拥有和访问 instance variables。我通过将 currentprior 分配给我的全局 _hold 对象来解决这个问题。
  • 出于某种原因 'this.pageTemplateLoaded' 我仍然失败了。但是,Loader.pageTempateLoaded 有效。

在进行此类操作时,阅读一篇非常有用的文章是 this one on MDN。那篇文章中的一句话值得在这里强调

The static keyword defines a static method for a class. Static methods are called without instantiating their class and cannot be called through a class instance. Static methods are often used to create utility functions for an application.

还值得注意的是

With this way of doing things there is no need to create an instance of the Loader class - it would do nothing useful even if you were to do so.