【问题标题】:Ruby on Rails - Why is Materialize.updateTextFields not a function?Ruby on Rails - 为什么 Materialize.updateTextFields 不是函数?
【发布时间】:2024-01-02 04:02:02
【问题描述】:

我有一个使用 material-saas gem 的 Ruby on Rails 项目。我最近注意到文本字段动画已停止工作。更具体地说,当文本字段处于活动状态时,标签不会在页面上向上移动,并且用户在输入字段中键入的任何内容都会覆盖标签文本并且看起来很糟糕。 Here (https://github.com/Dogfalo/materialize/issues/682) 是我遇到的风格问题的一个例子。除了标签文本没有正确移动之外,表单还有一个文件字段无法正常工作。当用户选择要上传的文件时,文件名不会出现在表单中,这是预期的行为。

我最近运行了rake assets:clobberrake assets:precompile,我想知道这是否与这个问题有关。

我做了一些研究,在 Material CSS 文档中他们说:

你也可以调用函数Materialize.updateTextFields();来 如果您是,请重新初始化页面上的所有 Materialize 标签 动态添加输入。

我尝试了这个修复,但是当我加载页面时,我的控制台中出现了Uncaught TypeError: Materialize.updateTextFields is not a function

这是我的表单视图:

<%= render 'shared/header' %>
<div class="container">
<h3>New Photo of the Day</h3>
<div class="row">
<%= form_for @photo, multiple: true do |f| %>

  <div class="input-field">
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

  <div class="input-field">
    <%= f.label :caption %>
    <%= f.text_area :caption, class: "materialize-textarea" %>
  </div>

  <%= f.label :date %>
  <%= f.date_field :date, class: "datepicker"%>

  <div class="file-field input-field">
    <div class="btn waves-effect waves-light yellow accent-4 white-text">
      <span>File</span>
      <%= f.file_field :image %>
    </div>
    <div class="file-path-wrapper">
      <input class="file-path validate" type="text">
    </div>
  </div>

  <div class="input-field center-align">
    <%= f.submit "Upload", class: "btn-large waves-effect waves-light"  %>
  </div>

<% end %>

这是我的 assets/application.js

//= require jquery
//= require materialize-sprockets
//= require jquery_ujs
//= require react
//= require react_ujs
//= require components
//= require_tree .

这是我的资产/custom.js

$(document).ready(function() {
  Materialize.updateTextFields();
});

这真的很奇怪,因为我知道表单样式的动画是有效的。我没有更改表单的代码。我唯一能想到的就是 clobber / precompile 命令,我需要运行它来对生产环境进行一些 ui 改进。

感谢您抽出宝贵时间查看此内容,感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails materialize


    【解决方案1】:

    在我看来有几个问题:

    Rails 很神奇,它可以做一些叫做“turbolinks”的事情。基本上,页面是动态替换的,而不是实际更改页面。它使您的网站更快,但并不总是发出相同的 Javascript 事件。

    您还需要 JQuery 2(我在 Dmitry 的建议下更新了我的答案)。

    将应用程序 JS 的前几行更改为:

    //= require jquery2
    //= require turbolinks
    //= require materialize-sprockets
    

    其次,我发现了物化库中存在的第二个错误。基本上,在涡轮链接加载页面之前,它不会定义updateTextFields()。为了解决这个问题,我有submitted a PR,但与此同时,我会通过将source 中的方法复制/粘贴到您的代码(在$(document).ready 内)来修补这个问题。使用类似的方法让您的代码在修复错误后得到更新(几乎是一个 polyfill)。

    Materialize.updateTextFields = Materialize.updateTextFields || // code from forms.js
    

    【讨论】:

    • 不好的建议。使用 jquery-turbolinks gem 通过 turbolinks 触发 jquery 事件。这里的问题是使用 jQuery 1,它完全破坏了 Materialize 的部分内容。
    • 变化是用//= require jquery2替换//= require jquery
    • @DmitryKudriavtsev 这是一个糟糕的解决方案,但它是我能想到的唯一一个。虽然我希望这是个坏建议,但库本身会监听 turbolinks:load 事件而不是 ready 事件,这意味着它只在导航后定义 Materialize.updateTextFeilds。可悲的是,只有三种方法可以解决此问题: 1 是更改代码本身以监听这两个事件(这需要我发送的 PR)。 2是自己触发turbolinks:load事件,但这可能会破坏其他库,3是自己定义方法(我的建议)。
    • 同样,jquery-turbolinks gem here 使它“正常工作”。
    • @DmitryKudriavtsev 查看自述文件,如果它使用$.ready(),它将“正常工作”,但materialize-sass gem 在加载事件本身时使用涡轮链接。该事件仅在页面更改后触发,而不是在初始加载时触发。
    【解决方案2】:

    您使用的是 jQuery 1.x。

    尝试使用 jQuery 2.x 或 3.x。

    来源:https://github.com/Dogfalo/materialize/issues/4593

    E:在您的设置中执行此操作的方法是将行 //= require jquery 更改为 //= require jquery2

    【讨论】:

    • 这是非常有用的文档。感谢您找到它。