Problem
jsFiddle Demonstration of the problem
http://jsfiddle.net/7sfaB/
I had a situation where I used AngularJS where I create a set of nested <ul> using ng-repeat with nested ng-repeat from a configuration service that contains a list structure. Inside this ng-repeat nested, I'm trying to use one complex model object, building the model dynamically based on the properties in the configuration service and binding to the input field. (eg ng-model="data[category.id][item.id].notes" )
Here is the HTML template:
<ul> <li id="{{category.id}}" ng-repeat="category in categoryConfig.categories"> <h3>{{category.title}}</h3> <ul> <li ng-repeat="item in category.items"> <p>{{item.title}} : Notes: <input type="text" ng-model="data[category.id][item.id].notes"/></p> <p>{{data[category.id][item.id].notes}}</p> </li> </ul> </li> </ul>
The problem I am facing is that if you try to edit the text field in the list, you will get the Cannot set property 'notes' of undefined error message on the console.
Interestingly, if you create an input field outside of ng-repeat that has an explicit model defined for one of the same bindings that was built dynamically, then the binding starts working even inside dynamically built models.
<p> Treasure Island Notes (dot syntax):<input type="text" ng-model="data.books.treasure_island.notes"/> </p>
Question
What is the correct way to install dynamically linked ng models so that it is immediately anchored and edited without the need for explicit model bindings? I was not sure if there was anything I needed to call in order to reregister the bindings after the ng-repeat loops completed.
Thanks in advance for any help you can provide.
For reference
Here is the configuration service that defines the structure of nested lists:
var app = angular.module('testApp', []); app.factory('configSvc', function(){ return { categories: [ { id: 'books', title: 'Books', items:[ { id: 'treasure_island', title: 'Treasure Island' }, ... ] }, { id: 'appliances', title: 'Household Appliances', items:[ { id: 'toaster', title: 'Toaster' }, ... ] } ] } })
And the controller that receives the data from the service:
app.controller('MainCtrl', function ($scope, configSvc) { $scope.categoryConfig = $.extend({}, configSvc); });