如何通过循环动态设置实例变量?

时间:2019-09-06 10:04:24

标签: javascript ruby-on-rails ruby braintree

我希望在一个页面上有多个braintree插件,具体取决于用户选择的订阅计划。我希望能够根据单击的内容来显示该插件。我在尝试如何在不预先设置令牌的情况下在一页上实现多次插入操作时遇到了麻烦。我尝试创建一个单击事件功能,但不确定是否正确执行了操作。

我尝试过:

<% @plans.map do |plan| %>
  <button onclick='braintreeClick()-<%= "#{plan.id}" %>'... > Click </button>
...
<% end %>
<script>
function braintreeClick-<%= plan.id %>() {
  var client_token = "<%= @client_token %>";
  ...
}
</script>

如果我从控制器设置了多个令牌,则我可以在页面上使用多种形式。

前一天晚上我尝试了几种不同的方法,但都失败了,例如:

@plans.map do |plan|
  @client_token_"#{plan.id}" = gateway.client_token.generate
end

并设置令牌:

var client_token = "<%= @client_token_"#{plan.id}" %>";

在上面一行的控制器中,这导致我的应用出现错误:unexpected '='

尝试了其他几种方式,例如:

@client_token(plan.id)

错误:unexpected '('

有什么方法可以动态设置我的实例变量,甚至可以更好地实现我的JavaScript,而无需对javascript和client_token进行硬编码?

在订购计划被删除或添加的情况下,我希望能够动态地进行设置。

2 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点:

第一个使用红宝石方法:instance_variable_setinstance_variable_get

# set new instance variable
instance_variable_set("@client_token_#{plan.id}", gateway.client_token.generate)

# read the instance variable
instance_variable_get("@client_token_#{plan.id}")

您还可以使用哈希代替实例变量,这样可能会更好

client_tokens = {}
@plans.map do |plan|
  client_tokens[plan.id] = gateway.client_token.generate
end

# and than read it with
client_tokens[plan.id]

如果您希望从更多的地方访问它而不是直接在视图中访问,则可以将其定义为实例变量@client_tokens = {}


如果您想将其更改为完全JS的东西。您可以执行以下操作:

<% @plans.map do |plan| %>
  <button onclick='braintreeClick("<%= gateway.client_token.generate %>")'... > Click </button>
...
<% end %>
<script>
function braintreeClick(client_token) {
  ...
}
</script>

您将生成令牌并将其直接放置到braintreeClick函数调用中,现在您根本不必理会实例变量或更多的ruby代码。这是比前两个更好的解决方案。


最好的解决方案可能是使用不引人注意的javascript调用。我不知道您使用什么JS框架,所以我将用jQuery进行演示:

<% @plans.map do |plan| %>
  <button class="js-brain-tree-button" data-client-token="<%= gateway.client_token.generate %>" ... > Click </button>
...
<% end %>
<script>
function braintreeClick(e) {
  var $button = $(e.currentTarget);
  var client_token = $button.data("client-token");
  ...
};

$(document).ready(function() {
  $(".js-brain-tree-button").on('click', braintreeClick);
});
</script>

注意:很抱歉,如果有错别字或错误,我没有测试代码,但是应该显示概念

答案 1 :(得分:1)

您要寻找的是instance_variable_set和类似的instance_variable_get方法。

在您的情况下,设置为:

@plans.each do |plan|
  instance_variable_set("@client_token_#{plan.id}", gateway.client_token.generate
end

然后您阅读:

var client_token = "<%= instance_variable_get("@client_token_#{plan.id}" %>";