I'm using AngularJS with Rails and creating dynamic nested form items which are not registering in the AngularJS scope. They are assigned the 'ng-dirty' class.
I have an investor which has three houses, in my Angular controller I only assign the first 2 as I really want to set these through Rails instead.
$ (event) ->
app = angular.module "investor", []
app.controller("InvestorCtrl", ["$scope", ($scope) ->
$scope.houses = [
{ cost: "295000", value: "450000" },
{ cost: "600000", value: "620000" }
]
$scope.calc_totals = ->
# Initialise variables
cost = 0
value = 0
# Go through each house and calculate the total cost
for h in $scope.houses
cost = parseInt(cost) + parseInt(h.cost)
value = parseInt(value) + parseInt(h.value)
# Set the total
$scope.total_cost = cost
$scope.total_value = value
# Run the calculation at the start
# $scope.calc_totals()
])
angular.bootstrap document, ['investor']
Here is my form
%div{"ng-controller" => "InvestorCtrl"}
= form_for(@investor) do |f|
- if @investor.errors.any?
#error_explanation
%h2
= pluralize(@investor.errors.count, "error")
prohibited this investor from being saved:
%ul
- @investor.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name, "ng-model" => "name"
- i = 0
= f.fields_for :houses do |builder|
.field
= render :partial => "house", :locals => {:f => builder, :i => i}
- i = i + 1
.field
= f.label :total_cost
= f.number_field :total_cost, "ng-model" => "total_cost"
.field
= f.label :total_value
= f.number_field :total_value, "ng-model" => "total_value"
.actions
= f.submit
If I type in the first or second house 'cost' or 'value' then it updates the total_cost, but if I update the third house it will not update the total_cost.
Is there a way to dynamically tell angularjs to listen to these elements without assigning them in the controller?
You're actually going about this a little wrong, IMO. Since Angular can (and will) be handling the rendering of your repeating HTML for you, you don't necessarily need to do your HTML rendering on the server. All you need from your server is some JSON. If you want it to be rendered right off the bat, you just make sure your initial values are set up properly when you initialize your controller.
Inject $http or a custom made service into your controller, and pull the data you want directly from the server in JSON format, then plug it into your scope. If your HTML and directives are set up properly it will just render. From there all other logic will be the same.
The web is moving forward. And by forward, I mean all of that HTML rendering stuff you used to do on the server is actually starting to be done on the client more and more. And that service layer you used to use to get your data on your web server? Well it is your web server now.
I know this isn't a direct answer to your problem, but it will greatly simplify what you're trying to do. Otherwise you have a balancing act to perform that will get maddening pretty fast.