AppGyver Supersonic 在视图之间导航并创建副本

AppGyver Supersonic navigating between Views and creating duplicates

我正在使用 AppGyver Steroids 和 Supersonic 构建应用程序,但我在以编程方式在视图之间导航时遇到了一些问题。

根据文档,您可以像这样在视图之间导航:

var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.push(view_obj);

然而,当我通过 Chrome DevTools 检查内容时,似乎创建了第二个重复视图,即如果我离开索引页面然后导航回来,我现在有两个索引页面,而不是 [我认为] 应该是一个。它也不会关闭我之前的视图。

如何防止这种情况发生并简单地移动到现有视图,而不是复制视图?离开视图后如何关闭视图?

谢谢。

尝试

var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.replace(view_obj);

然后看看 supersonic.ui.layers.pop();

您遇到的问题是每次导航时都会创建一个 new supersonic.ui.View("main#index")。最重要的是,我认为当您第二次导航回视图时,您希望 return 到相同的视图,即您希望视图保留在内存中,即使它已从导航堆栈中删除使用 pop() (而不是推送该视图的新实例)。为此,您需要预加载或“start()”视图,如文档 here.

中所述

我实现了自己的辅助函数来简化这件事;这是我的代码:

start = function(dest, isModal) {
  var viewId=dest,
      view=new supersonic.ui.View({
        location: dest,
        id: viewId
      });
  view.isStarted().then(function(started) {
    if (started) {
      if (isModal) {supersonic.ui.modal.show(view);}
      else {supersonic.ui.layers.push(view);}
    } else {
      // Start Spinner
      supersonic.ui.views.start(view).then(function() {
        if (isModal) {supersonic.ui.modal.show(view);}
        else {supersonic.ui.layers.push(view);}
        // Stop Spinner
      }, function(error) {
        // Stop Spinner
        A.error(error);
      });
    }
  });
};

start('module#view');一样使用它。作为奖励,您可以将 true 作为第二个参数传递,并将其作为模态推送。

它会检查您是否已经启动了一个视图 - 如果是,它只是将该视图推回堆栈。如果没有,它 start()s(即预加载)它,然后推送它。这确保视图保留在内存中(任何已修改的用户输入),即使您 pop() 它来自堆栈。

你要想象层栈其实就是计算机科学意义上的。您只能在堆栈顶部添加和删除视图。这样做的结果是复杂的导航如 A > B > C > D > B 是 difficult/hacky 做的(在这种情况下,你必须连续 pop() D 和 C 才能返回到 B).

如果您 pop() 他们的观点将关闭,只要您 没有 start() 他们。如果你这样做了,并且你 pop() 他们,他们就会留在记忆中。要终止该视图,您必须对其调用 stop(),如我在上面链接的文档中所述。

感谢 LeedsEbooks 帮助我解决了这个挑战。我能够找到解决方案。这是代码:

  var start = function(route_str, isModal) {

      var regex = /(.*?)#(.*)/g;
      var match_obj = regex.exec(route_str);

      var view_id_str = match_obj[2],
          view_location_str = route_str,
          view = new supersonic.ui.View({
              location: view_location_str,
              id: view_id_str
          });

      view.isStarted().then(function(started) {
          if (started)
          {
              if (isModal)
              {
                  supersonic.ui.modal.show(view);
              }
              else {
                  supersonic.ui.layers.push(view);
              }
          }
          else
          {
              // Start Spinner
              supersonic.ui.views.start(view).then(function() {
                  if (isModal)
                  {
                      supersonic.ui.modal.show(view);
                  }
                  else
                  {
                      supersonic.ui.layers.push(view);
                  }
                  // Stop Spinner
              }, function(error) {
                  // Stop Spinner
                  A.error(error);
              });
          }
      });
  };

您必须确保您的路线具有文档中定义的 module#view 格式。

请注意

超音速 ui 启动视图的方法似乎有些问题。如果您 运行 以下代码:

supersonic.ui.views.start("myapp#first-view");
supersonic.ui.views.find("first-view").then( function(startedView) {
    console.log(startedView);
});

您会注意到您的观点 idlocation 是相同的。这似乎是错误的,因为 id 应该是 first-viewlocation 应该是 myapp#first-view.

所以我决定不使用 AppGyver 方法,而是创建我自己的预加载方法,我 运行 从连接到我的主视图的控制器(这确保我想要预加载的所有视图都得到处理当应用程序加载时)。这是执行此操作的函数:

  var preload = function(route_str)
  {
      var regex = /(.*?)#(.*)/g;
      var match_obj = regex.exec(route_str);
      var view = new supersonic.ui.View({
          location: route_str,
          id: match_obj[2]
      });
      view.start();
  };

通过这样做,我确定视图将加载正确的 locationid,并且当我稍后使用我的 start() 函数时,我赢了没问题。

您需要确保您的 structure.coffee 文件没有任何 preload 说明,以免创建重复的视图,您以后会遇到问题。

最后,我有一个 2 级视图,它是一种通过 AJAX 操作发布数据的表单。当 AJAX 操作完成时,我希望视图返回到之前的视图。使用我之前的函数导致 push() 被拒绝。如果 AppGyver Supersonic 能够智能地检测到推送到上一个视图应该默认为 layers.pop 操作,那就太好了,但你并不总是能得到你想要的。无论如何,我设法使用 supersonic.ui.layers.pop() 解决了这个问题,它只是做了返回按钮会做的事情。

现在一切正常。