如何处理 tvOS MenuBarTemplate 选择?

How to handle tvOS MenuBarTemplate selection?

我设置并显示了一个基本的 MenuBarTemplate。

我如何对用户的菜单选择做出反应并加载适当的内容模板?

menuItem 标签中包含一个指向要加载的模板的 template 属性和一个设置为 menuBarItemPresenter.

presentation 属性
<menuItem template="${this.BASEURL}templates/Explore.xml.js" 
  presentation="menuBarItemPresenter">
    <title>Explore</title>
</menuItem>

然后您可以使用菜单栏的 MenuBarDocument 功能将文档关联到每个菜单栏项目。

menuBarItemPresenter: function(xml, ele) {
  var feature = ele.parentNode.getFeature("MenuBarDocument");
  if (feature) {
    var currentDoc = feature.getDocument(ele);
    if (!currentDoc) {
      feature.setDocument(xml, ele);
    }
  }

这假设您使用的是 Presenter.js file like the one in Apple's "TVML Catalog" sampleload 指定的函数调用 menuItempresentation 属性中指定的函数。

我想 TVML 和 TVJS 与 HTML 和 Javascript 相似。当我们想在用户界面中添加一些交互时,我们应该 addEventListener 到 DOM.

在 Apple 的 "TVML Catalog" 中,Presenter.js 是一个很好的例子,但它是抽象的,可以用在不同的 Present 动作中。

当我开发我的应用程序时,我编写了这个用于处理菜单栏选择的演示。

模块:loadTemplate.js

var loadTemplate = function ( baseURL , templateData ){
  if( !baseURL ){
    throw("baseURL is required");
  }
  this.BASEURL = baseURL;
  this.tpData = templateData;
}

loadTemplate.prototype.loadResource = function ( resource , callback ){
  var self = this;
  evaluateScripts([resource], function(success) {
      if (success) {
          var resource = Template.call(self);
          callback.call(self, resource);
      } else {
          var title = "Resource Loader Error",
              description = `There was an error attempting to load the resource '${resource}'. \n\n Please try again later.`,
              alert = createAlert(title, description);
          Presenter.removeLoadingIndicator();
          navigationDocument.presentModal(alert);
      }
  });
}

module.exports = loadTemplate; 

模块nav.js(使用menuBarTemplate):

import loadTemplate from '../helpers/loadTemplates.js'

let nav = function ( baseURL ){

  var loader = new loadTemplate( 
      baseURL , 
      {
        "explore" : "EXPLORE", 
        "subscribe" : "SUBSCRIBE", 
        "profile" :  "PROFILE", 
        "settings" : "SETTINGS" 
      }//need to use i18n here 
  ); 

  loader.loadResource(`${baseURL}templates/main.xml.js`, function (resource){

    var parser = new DOMParser();
    var navDoc = parser.parseFromString(resource, "application/xml");

    navDoc.addEventListener("select" , function ( event ){
      console.log( event );

      var ele = event.target,
      templateURL = ele.getAttribute("template");

      if (templateURL) {
        loader.loadResource(templateURL,

          function(resource) {
            if (resource) {
              let newParser = new DOMParser();
              var doc = newParser.parseFromString( resource , "application/xml" );

              var menuBarItemPresenter = function ( xml , ele ){
                var feature = ele.parentNode.getFeature("MenuBarDocument");
                if( feature ){
                  var currentDoc = feature.getDocument( ele );
                  if( !currentDoc ){
                    feature.setDocument( xml , ele );
                  }
                }
              };

              menuBarItemPresenter( doc , ele );
            }
          }
        );
      }
    });

    navigationDocument.pushDocument(navDoc);

  });//load from teamplate.

}

module.exports = nav;

我的代码不是最佳实践,但如您所见,您只需要 addEventListener 就像编写 Web 应用程序一样。然后你可以轻松处理 menuBarTemplate 选择,即使在 XHR 加载之后。

避免太多的回调,你应该一次又一次地重建你的代码。 :-)