1

I have 3 columns. The first lists a list of subjects from an array. Within that array, each subject has it's particular courses listed within, and within that, the rest of the course information.

Can I have the ng-repeat "function" operate properly if it is placed using a .innerHTML function?

I could be using the wrong identifiers to try and call content from the array, which could also be causing my problems.

scope:

$scope.subjects = [
    {text:'English', courses:[
        {coursesub:'English 1', coursedata:[
            {coursedesc:'test'}
        ]
        }
    ]
    },
    {text:'Mathematics'},
    {text:'Science'}
];

$scope.showDetail = function (todo) {
    document.getElementById("courselistings").innerHTML = '<a ng-repeat="course in subject.courses" class="list-group-item" target="#courseinformation" ng-click="showDetail(course)">{{courses.coursesub}}</a>';
};

html + angularjs:

<div class="col-md-3" id="subjects">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Subjects</h3>
                    </div>
                    <div class="panel-body">
                        <div class="list-group">
                            <a ng-repeat="subject in subjects" class="list-group-item" target="#courselistings" ng-click="showDetail(subject)">
                                {{subject.text}}
                            </a>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-3" id="courselisting">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Courses</h3>
                    </div>
                    <div class="panel-body">
                        <div class="list-group" id="courselistings">
                            test
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-6" id="courseinfo">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">Course Info</h3>
                    </div>
                    <div class="panel-body">
                        <div class="list-group" id="courseinformation">

                        </div>
                    </div>
                </div>
            </div>

I haven't done the courseinfo panel stuff yet, I just included it so that the columns would align properly.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Blake Stoddard
  • 191
  • 2
  • 4
  • 13
  • A similar question was brought up and solution here: http://stackoverflow.com/questions/5677799/how-to-append-data-to-div-using-javascript – jamesy829 Mar 05 '14 at 02:20
  • I looked at that question prior to asking this one and did not see how it helped answer mine? – Blake Stoddard Mar 05 '14 at 02:21
  • You should have a way to trigger the showDetail method, maybe make a link or button set to ng-click to trigger the method – jamesy829 Mar 05 '14 at 02:24

2 Answers2

1

No, it won't work.

You need to use template or directive.

http://docs.angularjs.org/guide/directive

You simple move innerHTML string to directive template

.directive('myCustomer', function() {
  return {
    scope: {
          subject: '='
    },
    template: '<string here>'
  };
});

And use it like

<my-customer subject="xxx"/>
Tim Green
  • 3,571
  • 2
  • 23
  • 23
1

A directive is a better answer for you. DOM manipulation should be done in directives, not controllers.

That said, it is possible using Angular's $compile which makes Angular aware of new HTML.

Just as a proof of concept- here's that function (and a working fiddle):

$scope.showDetail = function (todo) {
    var html= '<div><a ng-repeat="course in subjects['+todo+'].courses" class="list-group-item" target="#courseinformation" ng-click="showDetail(course)">{{course.coursesub}}</a></div>';
    var innerHTML =$compile(html)($scope) 
    var currente = angular.element(document.getElementById("courselistings"));

    currente.replaceWith(innerHTML);
}

In order for this to work we also need to pass in the index of the course you want to show -- ng-click="showDetail($index)". This is because the $compile will compile this against the controller scope, not the one inside the ngRepeat.

As you can see it takes jumping through a number of hoops to make this work- which is part of why a directive is better.

KayakDave
  • 24,636
  • 3
  • 65
  • 68