使用参数缓存URL视图/状态

Nam*_*mek 12 javascript angularjs angular-routing angular-ui-router

我正在使用Cordova和AngularJS制作移动应用程序.目前我已经安装了ui-router用于路由,但我对任何其他路由选择开放.

我的愿望:我想缓存某些与参数绑定的视图.换句话说,我想缓存路径(或页面).

示例情况:假设我们看到一些仪表板页面,点击一些重定向到路径的书籍封面book/2.此路径首次加载到应用程序中.路由器重定向HomeControllerBooksController(无论名称).现在BooksController加载给定的数据$stateParams(book id = 2)并创建充满所选书籍信息的视图.

在这种情况下我想要的是什么:

  1. 我回到仪表板页面 - 它已经加载(缓存?)
  2. 我再次选择书#2
  3. 控制器或路由器注意到已加载有关此书的数据
  4. 视图没有被重新创建,而是从缓存中获取

实际上,最好根据路径缓存我访问的所有内容.预加载也很酷.

原因:表现.当我打开一些书籍列表时,我希望它能够快速显示.每次创建视图时,页面更改的动画看起来很糟糕(它不是很平滑).

任何帮助,将不胜感激.

编辑:

首先,由于我认为这是许多移动HTML应用程序编程人员的常见问题,我想精确一些信息:

  1. 如果可能的话,我不是在寻找黑客,而是寻找明确的解决方案.
  2. 视图中的数据使用AngularJS,所以YES,有类似东西ng-bind,ng-repeat等等.
  3. 数据DOM元素 需要缓存.据我所知,浏览器的布局操作并不像重新创建整个DOM树那样昂贵.重画不是我们可以省略的.
  4. 拥有独立的控制器是很自然的事情.因为没有它我可以离开,我无法想象它是如何工作的.

我有一些半解决方案,但我会对我的愿望严格要求.

解决方案1.

将所有视图放入一个文件(我可以使用gulp builder)并使用ng-show.这是最简单的解决方案,我不相信任何知道AngularJS的人都不会想到它.

一个很好的技巧(来自@DmitriZaitsev)是创建一个辅助函数来显示/隐藏基于当前位置路径的元素.

好处:

  1. 这很简单.
  2. 预加载功能.

缺点:

  1. 所有视图都必须在一个文件中.不要问为什么不方便.
  2. 由于这一切都与移动设备有关,有时我想"清除"内存.我能想到的唯一方法是从DOM中删除这些孩子.肮脏但还可以.
  3. 我不能同时缓存/ book/2和/ book/3.我必须在每个使用参数绑定的视图的一些模板之上动态创建DOM子节点.

解决方案2.

使用来自ui-router-extras的 Sticky States和Future States 非常棒.

好处:

  1. 分开的看法.
  2. 非常简单的用法,非常简单,因为它只是一个插件ui-router.
  3. 可以创建动态子状态.所以可以缓存book1,book2但我不确定book/1book/2

缺点:

  1. 同样,我不确定,但我没有找到一个缓存 /元组的例子(view, parameters).除此之外它看起来很酷.

Dmi*_*sev 11

这正是我必须为我的网站33hotels.com解决的问题.你可以检查它并使用选项卡"过滤器"和"过滤器列表"(对应不同的路线),并看到视图立即更新,没有任何延迟!

我是怎么做到的?这个想法非常简单 - 摆脱路由器!

为什么?因为路由器的工作方式是在每次路由更改重新编译 View .是的,Angular会缓存模板,但不会缓存填充了数据的已编译视图.即使数据不变!结果,当我过去使用路由器时,开关总是感觉迟钝且无反应.每当我注意到令人讨厌的延迟时,它只是一小部分但仍然明显.

现在我使用的解决方案?不要重新编译你的意见!始终将它们放在DOM中!然后根据路线使用ng-hide/ ng-show隐藏/显示它们:

<div ng-show="routeIs('/dashboard')">
    <-- Your template for Dashboard -->
</div>

<div ng-show="routeIs('/book')">
    <-- Your template for Book -->
</div>
Run Code Online (Sandbox Code Playgroud)

然后routeIs(string)在你的内部创建一个函数Controller来测试是否$location.path()匹配string,或者string在我使用它时开始.这样我仍然可以获得所有视图的视图/book/2.这是我正在使用的功能:

$scope.routeBegins = function () {
    return _.some(arguments, function (string) {
           return 0 === $location.path().indexOf(string);               
    });
};            
Run Code Online (Sandbox Code Playgroud)

所以不需要聪明地使用缓存 - 只需将其保存在DOM中即可.它将为您缓存您的视图!

最好的部分是 - 无论何时更改数据,Angular都会立即更新DOM中的所有视图,甚至是隐藏的视图!

为什么这很棒?因为,作为用户,我不必等待所有的解析和编译,此刻我想看到结果.我想点击标签,立即查看我的结果!为什么网站会等我点击它然后开始所有的重新编译,因为我在等待?特别是在我的计算机闲置之前,这可以很容易地完成.

有什么缺点吗?我唯一能想到的是用更多DOM元素加载内存.但是,我的视图的实际字节大小可以忽略不计,例如与所有JS,CSS和图像进行比较.

另一个可能但可以避免的缺点是隐藏视图的重新编译成本.这是您可以变得聪明并避免计算繁重的部分,具体取决于当前路线.此外,您不会重新编译整个视图,只是受数据更改影响的部分,这也会降低计算成本.

我发现每个人都在使用Routes并且似乎完全没有意识到(或无知)这个问题.