在Rails项目中使用最小角度

Use minimal Angular in Rails project

本文关键字:Rails 项目      更新时间:2023-09-26

我想启动一个新的Rails项目,该项目将Angular.js用于.html.erb文件中的特定部分,但不是所有部分。这尤其意味着我不想使用Ember的路由功能,而是想使用Rails的路由功能。

作为一个例子,我想使用Angular来呈现一个具有例如排序和搜索功能的动态列表。这意味着一切,除了创建列表并赋予它功能之外,一切都是在Rails中完成的。一般来说,最好的方法是什么?

在Rails控制器中获取数据,将其传递给当前页面底部的Angular脚本(而不是单独的.js文件),然后由该脚本创建列表,这是一个好主意吗?(请参见以下示例)。还是应该将javascript代码放在一个单独的.js文件中?然后我如何将数据从Rails控制器传递给它?

这是示例代码。这是一个合适的解决方案吗?非常感谢!

<html ng-app="todoApp">
  <body>
    <div ng-controller="TodoController">
      <ul>
        <li ng-repeat="todo in todos">
          {{todo.title}}
        </li>
      </ul>
    </div>
    <script>
    angular.module('todoApp', [])
  .controller('TodoController', ['$scope', function($scope) {
    $scope.todos = <%= @array_from_rails %> // <-- pass the data from Rails to Angular
    </script>
  </body>
</html>

Angular应用程序通常喜欢使用JSON与服务器通信。最好将JavaScript代码放在.js文件中。它不应该是动态生成的——资产管道应该提供JS代码。

因此,您需要在Rails中设置一个API端点(例如/todos),以JSON格式传输所需的数据:

def index
  @todos = Todos.all
  respond_to do |format|
    format.json { render :json => @todos }
  end
end

然后,您可以定义一个带有服务(工厂)的Angular模块来与这个端点通信:

angular.module('todoApp', [])
.factory('TodosService', ['$http', function($http) {
  return $http.get('/todos');
});

并在控制器中使用此服务,在作用域上的数据可用时立即设置数据(请参阅$http上的文档)。


然后,只要您想使用在该模块中定义的功能,就只需要使用ng-app="todoApp",而无需显式输出生成的JS代码。它将加载您的模块并运行。

如果你需要在多个地方做这样的事情,我建议你定义一个全局模块和其中的多个控制器,因为Angular默认情况下只运行一个ng-app指令,但可以在任何时候加载控制器。然后你可以输出HTML代码,只要你需要,它就会"触发"Angular

请记住,如果您使用Angular,在使用其内部运行的部分时不会更改页面,因此所有通信(index/create/update/default)都应该通过JSONapi端点运行。