Reputation: 512
I've been using rails a while and am starting to fiddle around with integrating Angular.js. To get myself going, I'm making a simple (you guessed it) todo app.
In my rails controller, I've made a simple action to toggle a task between the "complete" and "incomplete" state - available at /tasks/:ID/complete
as a PUT
request.
def complete
@task = Task.find(params[:id])
@task.toggle!(:complete)
respond_with @task
end
My view lists all tasks, displaying their name next to a link, which, on click, I would like to call the "complete" action for that task.
<ul>
<li ng-repeat="task in tasks">
<a href="javascript:;" ng-click="completeTask(task.id)" class="complete-{{task.complete}}"></a>
{{task.name}}
</li>
</ul>
And finally, in my js controller (coffee script):
app = angular.module("TaskList", ["ngResource"])
@ListCtrl = ($scope, $resource) ->
Task = $resource("/tasks/:id", {id: "@id"}, {
update: {method: "PUT"}
complete: {method: "PUT"}
})
$scope.tasks = Task.query()
$scope.completeTask = (task_id) ->
Task.complete(task_id)
I'm not sure that "this" is even an available option in Angular, but I'm having some trouble with the documentation. Can anybody point me in the right direction while I get a handle on the best practices?
Thanks!
Upvotes: 1
Views: 1346
Reputation: 1676
So I have been fiddling around with angular+rails and reading a lot of documentation out there. I thought I would share some of the things I have found here that will help you out and answer some questions.
A lot of the documentation out there on rails and angular integrates the whole angular structure into your rails app like in this angular rails scaffold plugin https://github.com/patcito/angularjs_scaffold. I thought this was a really obtrusive way to insert angular into your app and it felt like I was swaying away from what made rails amazing, which was how it integrates its data into views.
I then stumbled upon these next two amazing resources. The always trusted Ryan Bates :), http://railscasts.com/episodes/405-angularjs?view=comments and this AMAZING youtube video http://www.youtube.com/watch?v=UjYIVwGbNC4 that talks about integrating rails and angular. These were the two most legitimate resources I could find that integrated angular in the format I wanted it integrated.
That may have seemed like a lot of info I was throwing at you, but after I digested all that information I started to understand how I will integrate angular and rails. Angular gives you a lot of options on how to implement things, so learning how you will choose to integrate it is up to you. So now let's get back to your question.
Based on what you are doing, you should be putting all that logic in the complete action in your angular controller. At least if you are trying to save the data in an AJAXy way. Here's what I would do to do what I think you want to do,
tasks_controller.rb
class TasksController < ApplicationController
respond_to :json
def index
@tasks = Task.all
end
def update
@task.find(params[:id])
respond_with @task.update_attributes(params[:task])
end
end
tasks.js.coffee
app = angular.module("TaskList", ["ngResource"])
#I created a factory of your task to abstract it a little
app.factory 'Task', ($resource) ->
$resource('/tasks/:id', {id: '@id'},
{update: {method: 'PUT'}})
@ListCtrl = ($scope, $resource) ->
$scope.tasks = Task.query()
$scope.completeTask = () ->
Task.save($scope.task)
views/tasks/index.html.erb
<ul>
<li ng-repeat="task in tasks">
<input type="checkbox"
<!-- This puts it in checked mode if the task is complete when the page is loaded -->
ng-checked="task.complete"
<!-- use this to utilize two-way-data-binding. -->
ng-model="task.complete"
>
<a ng-click="completeTask()" ng-class="completed:{{task.complete}}">
{{task.name}}
</a>
</li>
</ul>
I am relatively new to angular in rails, but I think this should work. It should be noted that there are probably 5 other acceptable solutions you could do for this with angular. I find angular provides lots of tools that can be implemented in different ways so you need to figure out the best format for your problem. Good luck!
Upvotes: 2
Reputation: 36
<ul>
<li ng-repeat="task in tasks">
<a ng-click="completeTask(task.id)" class="complete-{{task.complete}}"></a>
{{task.name}}
</li>
</ul>
You will need something to identify the task you are updating.
Upvotes: 0