Javascript Rails 4-从ajax中更新表单中的值或数据属性,并在if语句中使用此更新的值
我有一个Rails应用程序,Javascript Rails 4-从ajax中更新表单中的值或数据属性,并在if语句中使用此更新的值,javascript,jquery,ruby-on-rails,ajax,form-for,Javascript,Jquery,Ruby On Rails,Ajax,Form For,我有一个Rails应用程序,用户可以属于一个或多个团队。用户可以为每个团队创建想法。我希望Ideas的表单外观和行为略有不同,具体取决于用户所属的团队数量。如果用户不是任何团队的成员,则会显示此消息:您需要先创建团队,然后用户才能创建任何想法 我遇到的问题是,我使用Ajax创建团队。在ideas表格中,我目前有如下条件: - if current_user.teams.count == 0 You need to create a team first - else [..] 因为我使
用户可以属于一个或多个团队
。用户可以为每个团队创建想法。我希望Ideas
的表单外观和行为略有不同,具体取决于用户所属的团队数量。如果用户不是任何团队的成员,则会显示此消息:您需要先创建团队
,然后用户才能创建任何想法
我遇到的问题是,我使用Ajax
创建团队。在ideas表格中,我目前有如下条件:
- if current_user.teams.count == 0
You need to create a team first
- else
[..]
因为我使用Ajax创建团队,所以即使用户创建了他/她的第一个团队,也会显示此消息。当然,除非他/她重新加载该页面,否则它将正常工作。但我想有一个无缝的体验
所以这个条件,
- if current_user.teams.count == 0
需要更改为可以从js.erb
文件访问和更新的内容,我不太确定如何实现这一点
我想可能会使用一个隐藏的\u字段\u标记
,我可以在Ajax中更新它。但是我不确定我的if语句在视图中会是什么样子。我尝试了以下方法但没有成功(我使用了HAML
):
关于我应该做什么有什么想法吗?将数据从Rails传递到前端的最简单方法是通过路由(使用ajax访问)
如果您也通过ajax调用创建团队,那么我将创建一个函数来检查当前团队,并作为团队创建回调的一部分相应地更新您的视图
比如:
function updateDom(){
$('#myForm').text('On a team');
};
function checkTeam(){
$.get('/numTeams', function(data){
if (data.teams > 1){
updateDom();
}
})
};
function createTeam(args){
$.post('/createTeam', data, function(res){
checkTeam();
})
};
因此,当创建团队时,它将检查团队并相应地更新DOM
您还可以让js不断检查团队是否不同,并使用
var formText = window.setInterval(checkTeam, 1000);
底线是,任何动态的东西都将由js处理,而不是由rails处理(除了完全刷新页面以获得加载时填充的新信息之外) 我对本地存储的想法产生了反弹
如果您只关心当前用户的这一点,那么您可以这样做
编辑:计算团队数量,而不仅仅是检查是否有团队
编辑2:为什么还要使用本地存储?只要javascript变量就可以了
编辑3:事实上
在your view.html.erb中
在AJAX团队创建的javascript中
只需将您的包装在div
中,使用特定的id
和js.erb调用$('#')。hide()
@AbM我希望idea表单根据我的模型和控制器中的条件具有一些默认状态,与创建新团队无关。我不确定是否有好的方法将此类信息传递给JS文件。例如,在我的表单中,我还具有以下条件:current_user.teams.count>1…
,并且我根据该条件的结果隐藏/显示内容。你知道我是否可以将'current_user.teams.count'的值传递并访问到js.coffee文件中吗?使用本地存储来存储一个可以检查的布尔hasATeam怎么样?update.js.erb
作为对你的update
操作的响应,因此你确实可以访问其中的current_user.teams.count
。@AbM,我想我可以使用一个js.erb
文件。问题是这个表单几乎可以在整个应用程序的任何地方显示,因为它被放置在引导模式窗口中。我无法使用respond\u to
并在例如users/show
中呈现特定的js.erb文件。我很快尝试了您的方法,但遇到了一个问题。设置`localStorage.setItem('user_teams',current_user.teams.count);`在脚本标记内部,对于localStorage.getItem('user\u teams')
,会产生一个NaN
。我还尝试了:localStorage.setItem('user\u teams','')
,但是我没有得到当前用户.teams.count的值。关于如何将ruby嵌入JS标签有什么想法吗?哦,对不起,我刚刚意识到我忘记了
。不需要字符串分隔符“…”
或html\u-safe
,或者至少在我的ruby/rails上,没有它它它就可以完美工作,我可以看到值确实是使用Firefox调试器存储的。等等。。。。实际上,您甚至不需要本地存储!只要一个简单的javascript变量就可以了!谢谢,通过使用你的方法,它成功了。我认为这是最简单的解决方案,因为我在很多不同的视图/请求上展示了这个表单,表单几乎可以在每个页面上展示,因为它被放置在引导模式窗口中。与@Xavdidtheshadow给出的答案相比,使用此解决方案是否有任何安全或其他缺点?我能想到的唯一缺点是,如果有许多用户可能修改相同的数据(而不仅仅是当前用户修改自己的想法)。在这种情况下,您可能已经取消了nb_团队的同步
,但您最终可以将检查添加到控制器的相关部分,这样就不会出现问题。否则,您将受到保护。与@Xavdidtheshadow相比,它的另一个优点是更具反应性,因为没有发送用于检查团队数量的GET请求。谢谢!我认为你的解决方案会很好。正如我在上面的评论中提到的:“[…]认为我可以使用一个js.erb文件。问题是,这个表单几乎可以在整个应用程序的任何地方显示,因为它位于引导模式窗口中。我无法使用respond_在例如users/show中呈现特定的js.erb文件。”因此,它实际上并不与特定的请求/路由相关联。你知道是否可以从用户/show
中渲染/ideas/new.js.erb
?是的!您可以使用这里描述的方法:在任何地方渲染.js.erb。
var formText = window.setInterval(checkTeam, 1000);
...
<%= if current_user.has_teams %>
<script>
/* Using local storage : */
localStorage.setItem('nb_teams', <%= current_user.teams.count %>);
/* ...Hey ! We can just add a javascript variable */
var num_teams = <%= current_user.teams.count %>
</script>
<% end %>
....
/* Local storage only : */
num_teams = parseInt(localStorage.getItem('nb_teams'))
if( num_teams === 0){
alert("You don't have any team !");
} else if (num_teams ===1) {
// Normal case
} else if (num_teams >= 2){
alert("Please select a team")
}
function createTeam(){
....
$.post(....)
.success( function(){
/* Local storage */
num_teams = parseInt(localStorage.getItem('nb_teams'))
localStorage.setItem('nb_teams', num_teams+1);
/* Plain old javascript */
num_teams ++;
})
}