How do I load an external HTML file and have the scope variables renderred properly in angularJS?

StackOverflow https://stackoverflow.com/questions/22918474

  •  29-06-2023
  •  | 
  •  

Question

What I am trying to do is after clicking on a buddy in the buddy list, load a chat dialog template HTML file without disturbing other elements in current DOM just like chatting in facebook.

My problem is that after loading the html template file the scope variables such as {{contact.jid}} are not properly rendered, and the controller for the dialog is not even called.

How can I force a rerender or a call on the controller so that those variables are properly renderred? Or should I not use the jQuery.load function to do this? I can't figure out any other way.

Thank you.

Code of the controllers:

// Controller for the chat dialog
ctrl.controller('ChatCtrl',function($scope){
    $scope.test = "Test"
});

// Controller for the buddy list
// $scope.toggleDialog is called when a buddy is clicked
ctrl.controller('ContactCtrl',function($scope){
    $scope.contacts = window.contactList;
    $scope.toggleDialog = function(to){
        $.("#chatarea").load("chatdialog.html")
    };
});

The controller function of chat dialog is not called after loading chatdialog.html which has an attribute of ng-controller, so the {{test}} variable is not set.

Was it helpful?

Solution

You need to wrap your content that will be compiled inside a directive.

This directive receives the variables and the HTML that will be compiled. You can wrap this directive in the element that you like:

http://plnkr.co/edit/RYVCrlDmgVXT3LszQ9vn?p=preview

For example, given the following html and variables:

// In the controller
$scope.controllerHtml = '<span>{{variables.myVariable}}</span>';
$scope.controllerVariables = {myVariable: 'hello world'};

<!--In the HTML-->
<div compile-me html-to-bind="controllerHtml" variables="controllerVariables"></div>

You will get the following:

<div>
    <span>hello world</span>
</div>

OTHER TIPS

You are loading the external HTML via jQuery and Angular has no way of knowing how to use it. There are two ways to solve this issue:

  1. use ngInclude to load the template from the server, angular will load it from the server and compile it for you to use.
  2. continue to use jQuery load the HTML from the server and use the $compile service to teach angular how to use it

I would highly suggest using method #1 to load your external template.

I suppose the:

$.("#chatarea").load("chatdialog.html")

is the jQuery .load, or something similar. I would get the template via ngInclude, checking if test is setted or not; html:

<div id="chatarea" ng-if="test">
  <div ng-include="'chatdialog.html'"/>
</div>

controller:

ctrl.controller('ContactCtrl',function($scope){
    $scope.contacts = window.contactList;
    $scope.test = '';
    var callbackFunction = function(data) {
      $scope.test = data.test;
    };
    $scope.toggleDialog = function(to){
      AjaxRequestToGetBuddyInfoAndMessages(to, callbackFunction);
    };
});

Obviously test will be a more complex object, so the ngIf test will be different (and you will need to take into account the fact that:

$scope.test = data.test

if they are objects, they will lose the reference and have an unwanted behaviour).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top