【问题标题】:Single page application with Rails 4 and AngularJS使用 Rails 4 和 AngularJS 的单页应用程序
【发布时间】:2013-11-05 13:11:17
【问题描述】:

好的,这个想法可能看起来有点疯狂,而且有点疯狂(至少在我的水平上是这样)。 我有一个相当标准的 Rails 应用程序(一些内容页面、一个博客、一个新闻块、一些身份验证)。我想把它做成一个单页应用程序。

我想要完成的是:

  1. 所有页面都是通过AJAX 获取的,就像使用turbolinks 时一样,除了AJAX 只返回view part(布局中的yield 部分)而没有布局本身,它保持不变(更少的数据在响应,更快的渲染和加载时间)。
  2. 这些页面大多只是带有 AngularJS 标记的静态 html,因此不需要处理太多。
  3. 所有实际数据都通过 JSON 单独加载并填充到视图中。
  4. 网址和页面标题也会相应更改。

我已经考虑这个概念很长一段时间了,但我似乎无法提出解决方案。在这一点上,我已经有了一些关于如何实际完成的想法以及一些我无法通过的问题。非常感谢任何想法或解决方案。或者可能是我刚刚发疯了,加载页面的 3 个小请求比我需要在服务器端完成所有渲染的大请求更糟糕。

所以,这是我的想法和已知问题。

  1. 当用户第一次访问应用程序时,会定期渲染带有角度标记的视图模板,第二个请求来自Angular Resource
  2. 然后在 ngClick 上任何将地址发送到内容包装器的 ngInclude 的链接。
    1. 如何在任何链接上绑定 onClick 以及如何从该绑定中排除某些链接(例如,指向外部身份验证服务的链接)?
    2. 如果请求来自 Angular,我如何告诉服务器不要呈现布局?我想为请求添加一个参数,但可能有更好的主意。
  3. 当 ngInclude 获取请求的模板时,它会触发该模板中控制器(通常是单个)的 ngInit 函数,并以 JSON 格式从服务器获取数据(以及正确的页面标题)。
  4. Angular 使用接收到的数据填充模板,将浏览器 url 设置为链接的 url,并将页面标题设置为刚刚获得的内容。
    1. 如何更改页面标题和页面 URL?可以使用 jQuery 更改标题,但有没有通过 Angular 本身的方法?
    2. 再一次,我一直在考虑某种动画,以使这种变化更加花哨。
  5. 利润!

所以。大家觉得呢?

【问题讨论】:

  • 我认为你需要花一些时间学习 Angular。如果你已经完成了基础教程,这个问题就没有意义了。 docs.angularjs.org/tutorial
  • @Emmentaler 我已经完成了那个教程。但我不想在 Angular 控制器中复制所有路由并将路由留给服务器。还有一些模板需要在服务器端预渲染,所以我不能只是将它们移动到 public/templates/ 目录并让 angular 自己拾取它们。
  • 我的看法是你问错地方了,试试javascriptroom.com (Too Localised)
  • 如果你在服务器上渲染,那么 Angular 不是一个好的选择。 Angular 的主要目的之一是为您提供与在典型服务器环境(JSP、JSF、PHP)中完全在客户端上获得的模板和绑定相同的好处。就我个人而言,我不会将这两种范式混为一谈。
  • 如果它是单页应用程序......服务器路由与什么有什么关系?客户端中的路由是基于哈希的。我同意@Emmentaler。这个问题没有任何意义,看起来你真的没有很好地掌握角度方法。至于页面标题试试document.title

标签: ajax angularjs ruby-on-rails-4 single-page-application


【解决方案1】:

好的,以防万一有人发现这个想法值得思考。 关键可以解决如下。

服务器端决定是否渲染视图。

ngInclude 中使用一个参数,如果该参数存在,则在控制器中设置layout: false。 还没有找到更简单的方法。

客户端绑定所有链接,除了具有特定类 no-ajax 的链接 这是执行此操作的指令。

App.directive('allClicks', function($parse) {
    return {
      restrict: 'A',
      transclude: true,
      replace: true,
      link: function(scope, element, attrs) {
        var $a = element.find('a').not($('a.no-ajax')),
            fn = $parse(attrs['allLinks']);
        $a.on('click', function(event) {
          event.preventDefault();
          scope.$apply(function() {
            var $this = angular.element(event.target);
            fn(scope, {
              $event: event,
              $href: $this.attr('href'),
              $link: $this
            });
          });
        });
      }
    };
  }) 

然后在一些包装器上使用它 divbody 标签,如 <body ng-controller="WrapperCtrl" all-links="ajaxLink($href)">,然后在你的内容 div 中使用 <div id="content" ng-include="current_page_template">

在您的角度控制器中,将 current_page 模板设置为 document.URL 并实现该 ajaxLink 函数。

$scope.ajaxLink = function(path) {
   $scope.current_page_template = path+"?nolayout=true";
} 

然后,当您从服务器获取带有数据的 JSON 时,不要忘记使用 history.pushState 设置 url 行并使用 document.title = 设置标题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2016-09-01
    相关资源
    最近更新 更多