让 Dojo 在 Rails 上与 Ruby 一起工作 4

Getting Dojo to Work with Ruby on Rails 4

我正在将我的 symfony 应用程序移植到 Rails 4.2.0 上的 Ruby。我的设置在 symfony 中运行良好。 this old post 关于如何将 dojo 与 RoR 结合使用,但它使用了已弃用的代码。

在我的 application.html.erb 我有

<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>

我用 Rails 替换了 symfony 包装器。我还更改了道场版本。我使用的是 1.9.1。 Rails 生成此 html:

<script>
dojoConfig = {async: true}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js">

最后一行后面是一堆压缩的javascript和Firebug中的关闭脚本标签。

我在测试此代码的 home/index.html.erb 中没有进行任何更改。在 app/assets/javaascipts/home.js 中,我有:

//require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
ready(function()
{
var head = "<div class='footnote-text'>";
var tail = "</div>";
var fnt1 = head + dom.byId("fnb1").innerHTML + tail;
var fnt2 = head + dom.byId("fnb2").innerHTML + tail;
var fnt4 = head + dom.byId("fnb4").innerHTML + tail;

new Tooltip({ connectId: ["footnote1"],position:["after","above","below"],label: fnt1 });
new Tooltip({ connectId: ["footnote2"],position:["after","above","below"],label: fnt2 });
new Tooltip({ connectId: ["footnote4"],position:["after","above","below"],label: fnt4 });
new Tooltip({ connectId: ["footnote5"],position:["after","above","below"],label: fnt4 });
});
});
//require(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
define(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
ready(function(){
var fnt3 = dom.byId("fnb3").innerHTML;

myDialog = new Dialog({
  title: "Contact Me",
  content: fnt3,
  style: "width: 300px"
});
});
});

被注释掉的 require 行是我在我的 symfony 应用程序中使用的。如您所见,我按照 dojo 站点上的描述将它们替换为 define 。当我 运行 它时,我在 Firebug 控制台上收到以下错误:

ReferenceError: define is not defined
...define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip

如果我使用 require 而不是 define,我会得到 require is not defined。

更新

我尝试将 dojo 安装到应用程序中并取得了一些进展。我从 dojo 复制了下载到 vendor/assets/javascript/dojo。 dojo 目录包含子目录 dojo、dojox 和 digit

然后我添加了

//= require dojo/dojo/dojo.js

到app/assets/javascript/application.js。我还在 home.js 文件中将定义改回 require。当我重新加载页面时,我收到一条错误消息,抱怨找不到工具提示。然后我补充说:

//= require dojo/dijit/Tooltip.js

重新加载时它抱怨一堆其他丢失的 js 文件。这与我在使用 symfony 时遇到的问题相同,这就是我访问 google 图像的原因。我怎样才能到达 rails 来搜索供应商目录中的文件?这是错误之一:

"NetworkError: 404 Not Found - http://amcolan.loc/dijit/_base/manager.js"

更新 2

由于 require_tree 适用于应用程序资产,我认为它也适用于供应商。我加了

//= require_tree ../../../vendor/assets/javascripts/dojo

到我的 application.js 文件。当我重新加载页面时,大约需要一分钟。我的猜测是它正在加载 dojo 目录树中的所有内容,这并不奇怪。页面加载完成,没有任何错误。当我将鼠标悬停在工具提示项上时(代码的目的是显示工具提示),Firebug 出现大约两千个错误并退出。所有错误似乎都是 "ReferenceError: define is not defined"

更新 3

我回去使用 googleapi。我的 application.html.erb header 看起来像这样

<head>
  <meta charset="UTF-8">
  <title><%= content_for?(:title) ? yield(:title) : "American Colonial Ancestors" %></title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <script>dojoConfig = {async: true}</script>
  <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>

我颠倒了 javascript 包含的顺序。页面重新加载没有错误。工具提示不起作用,但当我将鼠标悬停在某个项目上时它不会产生任何错误。我在 home.js 代码中放了一个错误的语句,它出现在控制台上,所以我知道代码正在被解析。我的页面设置可能有一个错误。

可能有不止一种方法可以让 Dojo 工具包在 Rails 上与 Ruby 一起工作。如果不是最有效的方法,这是最简单的方法。这适用于 Rails 4.2.0。我想它也适用于其他版本。

在 views/layouts/application.html.erb 中,在包含站点脚本之前添加以下内容:

<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>

将版本更改为最新版本或您想要使用的版本。这里我使用的是 1.10.3 版本。道场网站说还有其他 CDN(内容交付网络)的源代码。我在他们的示例中使用 google 。以下是我的头部部分的相关部分:

<head>
  <meta charset="UTF-8">
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>
  <script>dojoConfig = {async: true}</script>
  <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= content_for :page_script %>
  <%= csrf_meta_tags %>
</head>

如果您要使用任何工具包的对话框、工具提示等,您需要通过添加如下内容来包含样式表:

<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>

将版本和主题更改为您自己的要求。这里我使用的是 claro 主题。你可以在我上面的头部部分看到它。我不认为位置很重要。您还需要在正文声明中声明您的主题 class。这是我的:

<body class="claro">

关于该主题的 older post 具有不同的 javascript 格式。我认为不需要任何特别的东西。这是一个工作脚本的示例:

require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
  ready(function()
  {
    var head = "<div class='footnote-text'>";
    var tail = "</div>";
    var fnt1  = head + dom.byId("fnb1").innerHTML + tail;
    var fnt2  = head + dom.byId("fnb2").innerHTML + tail;

    new Tooltip({connectId: ["footnote1"], position:["after","above","below"], label: fnt1 });
    new Tooltip({connectId: ["footnote2"], position:["after","above","below"], label: fnt2 });
  });
});

如我的问题所述,我尝试将 Dojo Toolkit 源放在 vendor/assets/javascript 中。从 1.7 版开始,dojo 开始使用异步模块定义 (AMD)。可能是 AMD 加载程序与 Rails 预编译功能不兼容。我对它的了解还不够肯定。