Micropost字符倒计时(Rails教程,第2版,第10章,练习7)
我尝试了The Rails教程(第10章,练习7)中的微博字符倒计时,使用此处的信息作为基础,并在 此处和此处获得StackOverflow答案的帮助。
在屏幕上,它看起来像这样 ,当你接近字符限制时,文本逐渐变红,一旦微博超过限制,Post按钮禁用,完成就像这样 。
目前的实现如下:
视图/共享/ _micropost_form.html.haml
= form_for @micropost do |f| = render 'shared/error_messages', object: f.object .field= f.text_area :content, placeholder: t('.compose_micropost') %span .remaining= t('.characters_remaining').html_safe .countdown = f.submit t('.post'), class: "btn btn-large btn-primary"
资产/ Java脚本/ microposts.js.coffee
updateCountdownAttributes = (toRemove, toAdd = null) -> for attr in toRemove $(".remaining, .countdown").removeClass attr if toAdd $(".remaining, .countdown").addClass toAdd if toAdd is "overlimit" $("input.btn.btn-large.btn-primary").attr("disabled", "true") else $("input.btn.btn-large.btn-primary").removeAttr("disabled") updateCountdown = -> remaining = 140 - $("#micropost_content").val().length toRemove = ["nearlimit", "almostlimit", "overlimit"] if remaining > 19 updateCountdownAttributes(toRemove) if remaining attr is "nearlimit").toString() updateCountdownAttributes(toRemove, toAdd) if remaining attr is "almostlimit").toString() updateCountdownAttributes(toRemove, toAdd) if remaining attr is "overlimit").toString() updateCountdownAttributes(toRemove, toAdd) $(".countdown").text remaining $(document).ready -> $(".countdown").text 140 $("#micropost_content").change updateCountdown $("#micropost_content").keyup updateCountdown $("#micropost_content").keydown updateCountdown $("#micropost_content").keypress updateCountdown
资产/样式表/ custom.css.scss
... /* Micropost character countdown */ .remaining, .countdown { display: inline; color: $grayLight; float: right; } .overlimit { color: $red; } .almostlimit { color: hsl(360, 57%, 21%); } .nearlimit { color: $gray; }
配置/语言环境/ en.yml
en: ... shared: ... micropost_form: compose_micropost: "Compose new micropost..." post: "Post" characters_remaining: " characters remaining."
从这里,我有两个问题/问题:
第一个是,如果可能的话,我希望能够对“剩余字符”字符串进行适当的复数化。 也许是这样的:
视图/共享/ _micropost_form.html.haml
... %span .remaining= t('.characters_remaining', count: [[.countdown value]]).html_safe .countdown ...
配置/语言环境/ en.yml
... micropost_form: ... characters_remaining: one: " character remaining." other: " characters remaining."
但是,我不知道如何在.countdown
div中检索值,我可以将它传递给count
参数。 我怎样才能做到这一点?
假设第一个问题可以解决,我也想摆脱减号字符,而是将“-2个字符剩余”改为“2个字符以上”。 也许在视图中使用某种分支逻辑和一些javascript将负数更改为正数…? 我在这里不太确定,所以任何帮助都会受到赞赏。
视图/共享/ _micropost_form.html.haml
... %span - [[ if .countdown value < 0 ]] .remaining= t('.characters_over', count: [[positive .countdown value]]).html_safe - [[ else ]] .remaining= t('.characters_remaining', count: [[.countdown value]]).html_safe .countdown ...
配置/语言环境/ en.yml
... micropost_form: ... characters_remaining: one: " character remaining." other: " characters remaining." characters_over: one: " character over." other: " characters over."
我也正在阅读本教程,并发现这篇文章,虽然我喜欢你添加的css使这看起来一致(我已经把它作为我自己:) :)我认为你的解决方案过于复杂。 对我来说,这只是两个变化:js脚本并将脚本添加到我的视图中。
我的JS文件:character_countdown.js
function updateCountdown() { // 140 characters max var left = 140 - jQuery('.micropost_text_area').val().length; if(left == 1) { var charactersLeft = ' character left.' } else if(left < 0){ var charactersLeft = ' characters too many.' } else{ var charactersLeft = ' characters left.' } jQuery('.countdown').text(Math.abs(left) + charactersLeft); } jQuery(document).ready(function($) { updateCountdown(); $('.micropost_text_area').change(updateCountdown); $('.micropost_text_area').keyup(updateCountdown); });
这是我将它添加到视图中的位置
<%= form_for(@micropost) do |f| %> <%= render 'shared/error_messages', object: f.object %>
请让我知道你在想什么 :)
我已经找到了解决我的问题(多元化和摆脱所有语言环境中的减号)的解决方案,我觉得这很好,所以我会在这里详细解释,希望有人会觉得它很有用。
如果您想深入研究细节之前看看它是什么样的,您可以在Heroku的Sample App部署中亲自尝试一下。
配置
这个解决方案使用了i18n-js gem,它是“在Javascript上提供Rails I18n翻译的小型库”。 gem很棒,但遗憾的是我并没有像我想的那样和Heroku玩得很好,而且在可预见的未来它似乎不会 。 因此,需要更改以下配置:
配置/ application.rb中
# ... config.assets.initialize_on_precompile = true
这意味着在每次部署到Heroku之前,需要运行rake assets:precompile
,并且一旦确认成功部署,运行rake assets:clean
以再次开始开发资产。 如果这太烦人了,你需要另一个解决方案。
更新 :
如果在Heroku环境中启用
user-env-compile
,则可以让Heroku预编译您的资产并仍然使用i18n-js gem。 关于如何操作的说明在这里 ,我认为只要Heroku支持该function,它就值得做。
解决方案
的Gemfile
# ... gem 'i18n-js', '2.1.2'
应用程序/资产/ JavaScript的/ application.js中
// ... //= require i18n //= require i18n/translations
由于上面的Heroku设置,此时我需要运行
$ rake i18n:js:setup
将i18n-js.yml复制到config文件夹。
应用程序/视图/布局/ application.html.haml
%html %head # ... = render 'layouts/i18n_js'
应用程序/视图/布局/ _i18n_js.html.haml
:javascript I18n.defaultLocale = "#{I18n.default_locale}"; I18n.locale = "#{I18n.locale}";
应用程序/视图/共享/ _micropost_form.html.haml
# ... .field= f.text_area :content, placeholder: t('.compose_micropost') %span.countdown = f.submit t('.post'), class: "btn btn-large btn-primary"
应用程序/资产/样式表/ custom.css.scss
/* Micropost character countdown */ .countdown { display: inline; color: $grayLight; float: right; } // ...
应用程序/资产/ JavaScript的/ microposts.js.coffee
(我用javascript / coffeescript不太好,所以这里有改进/重构的空间)
updateCountdownString = (remaining) -> if remaining > 1 or remaining is 0 $(".countdown").text I18n.t('shared.micropost_form.characters_remaining.other', count: remaining) else if remaining is 1 $(".countdown").text I18n.t('shared.micropost_form.characters_remaining.one', count: remaining) else if remaining is -1 $(".countdown").text I18n.t('shared.micropost_form.characters_over.one', count: -remaining) else $(".countdown").text I18n.t('shared.micropost_form.characters_over.other', count: -remaining) takeFromCollection = (collection, className) -> (collection.filter (attr) -> attr is className).toString() updateCountdownAttributes = (remaining) -> toRemove = ["nearlimit", "almostlimit", "overlimit"] if remaining < 20 toAdd = takeFromCollection(toRemove, "nearlimit") if remaining < 11 toAdd = takeFromCollection(toRemove, "almostlimit") if remaining < 0 toAdd = takeFromCollection(toRemove, "overlimit") if toAdd isnt null for attr in toRemove $(".countdown").removeClass attr $(".countdown").addClass toAdd if toAdd is "overlimit" $("input.btn.btn-large.btn-primary").attr("disabled", "true") else $("input.btn.btn-large.btn-primary").removeAttr("disabled") updateCountdown = -> remaining = 140 - $("#micropost_content").val().length updateCountdownString(remaining) updateCountdownAttributes(remaining) $(document).ready -> $(".countdown").text I18n.t('shared.micropost_form.characters_remaining.other', count: 140) $("#micropost_content").on("change keyup keydown keypress paste drop", updateCountdown)
config / locales / en.yml (其他语言环境在同一样式中具有相同的键)
shared: # ... micropost_form: characters_remaining: one: "%{count} character remaining." other: "%{count} characters remaining." characters_over: one: "%{count} character over limit." other: "%{count} characters over limit."