首页 > 解决方案 > 如何通过循环动态设置实例变量?

问题描述

根据用户选择的订阅计划,我希望在一页上有多个 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 进行硬编码?

我希望能够在删除或添加订阅计划的情况下动态设置它。

标签: javascriptruby-on-railsrubybraintree

解决方案


有几种方法,如何做到这一点:

第一个是使用 ruby​​ 方法: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>

注意:对不起,如果有一些错别字或错误,我没有测试代码,但它应该显示概念


推荐阅读