16

I'm making an in game UI using awesomium, at some points the game loads up and executes a chunk of javascript which is meant to create arbitrary new UI elements. e.g.

jQuery(document.body).append('<span class="game-status-alert">You Lose!</span>');

That works nicely, the problem comes when I want to create some slightly more advanced UI elements, specifically using angular. For example something like:

function ChatBoxControl($scope) { /* Stuff */ }

jQuery(document.body).append(
    '<div ng-controller="ChatBoxControl"><div ng-repeat="line in chat"><span>{{line}}</span></div></div>'
);

Not surprisingly, this does not create a new angular view. It simply adds that html to the document and never binds to the ChatBoxControl.

How can I achieve what I'm trying to do here?

Martin
  • 12,469
  • 13
  • 64
  • 128

2 Answers2

23

You should $compile dynamically added angular content. Something like:

jQuery(document.body).append(
    $compile(  
        '<div ng-controller="ChatBoxControl"><div ng-repeat="line in chat"><span>{{line}}</span></div></div>'
    )(scope)
);

scope for any element you can get using something like:

var scope = angular.element('#dynamicContent').scope();

Also you should get $compile that can be injected in other controller.

See also: AngularJS + JQuery : How to get dynamic content working in angularjs

Community
  • 1
  • 1
Artem Andreev
  • 19,942
  • 5
  • 43
  • 42
  • I'm going to accept this answer, since it uses strings of html and not a reference to a HTML file and is thus closer to my original question :) – Martin Aug 21 '12 at 13:16
5

You might want to use ng-include combined with ng-repeat. Here is an simple example: http://plunker.no.de/edit/IxB3wO?live=preview

  <div ng-repeat="dom in domList" ng-include="dom"></div>

Parent $scope will keep the list of partials loaded into the view. And ng-repeat + ng-include will iterate over and display partials according to the list.

When it is the right timing, you can append the partial into the dom list. e.g.

$scope.domList.push("chatbox.html");

(BTW, putting DOM manipulation into controller is not the angular way.)

Tosh
  • 35,955
  • 11
  • 65
  • 55
  • I understand that DOM manipulation isn't the angular way, but unfortunately it is unavoidable due to the way the game UI system works :( – Martin Aug 21 '12 at 13:15
  • By angularjs, it looks like if controller makes DOM manipulations, it's more a "service" then a controller. The service can be then injected into Controller for use. But again, services should have as low amount as possible of DOM manipulations, since then it not testing friendly. – Alex Dn Feb 04 '13 at 09:05