1

I have a HTML page with different sections, which are loaded with AJAX. I have created a controller for each of the sections.

How is possible to bind the controller on a section which has been dynamically added on HTML?

I have found very complicated solutions, which i don't even know if they apply.

I need the most basic, easiest solution, something similiar with ko.applyBindings($dom[0], viewModel) for the ones who worked with KnockoutJs.

Index html

<div class="row" ng-app="app">
    <div class="col-xs-3">
        <ul class="nav nav-pills nav-stacked">
            <li>
                <a href="#/profile">Profile</a>
            </li>
        </ul>
    </div>
    <div class="col-xs-9">
        <div id="container"><!-- load dynamic HTML here --></div>
    </div>
</div>

Dynamic HTML

<div ng-controller="profile">
    First Name: <input type="text" ng-model="firstName"><br>
    Last Name: <input type="text" ng-model="lastName"><br>
    <br>
    Full Name: {{firstName + " " + lastName}}
</div>

Javascript:

var app = angular.module('app', []);

app.controller('profile', function ($scope) {
    $scope.firstName = "John";
    $scope.lastName = "Doe";
});

// load new HTML
// normally this is triggered by a link / button
$(function () {
    $.get("/EditProfile/Profile", function (data, status) {
        $("#container").html(data);
    });
});

enter image description here

Catalin
  • 11,503
  • 19
  • 74
  • 147
  • The top answer on this - http://stackoverflow.com/questions/18157305/angularjs-compiling-dynamic-html-strings-from-database is a very good solution for this problem. – FrailWords Dec 29 '15 at 14:06

1 Answers1

1

Don't use jQuery to embed html to your container. If you use jQuery, AngularJS can't track DOM manipulations and trigger directives. You can use ng-include directive of AngularJS.

In index.html file:

...
<div id="container">
   <div ng-include="'/EditProfile/Profile'"></div>
</div>
...

If you want you can make that conditional:

...
<div id="container">
   <div ng-if="profilePage" ng-include="'/EditProfile/Profile'"></div>
</div>
...

With that example, if you set profilePage variable to true, profile html will be load and render by ng-include.

For detailed info take a look to ngInclude documentation.

By the way, best practice to include views to your layout by triggering same link clicks is using routers. You can use Angular's ngRoute module or uiRouter as another popular one.

If you use ngRoute module, your index.html looks like that:

<div class="row" ng-app="app">
    <div class="col-xs-3">
        <ul class="nav nav-pills nav-stacked">
            <li>
                <a href="#/profile">Profile</a>
            </li>
        </ul>
    </div>
    <div class="col-xs-9">
        <div id="container" ng-view><!-- load dynamic HTML here --></div>
    </div>
</div>

And with a router configuration like below, profile html will be automatically loaded and rendered by ngRoute inside ngView directive:

angular.module('myapp', []).config(function($routeProvider) {
  $routeProvider
   .when('/profile', {
    templateUrl: '/EditProfile/Profile',
    controller: 'ProfileController'
  });
});
Murat Çorlu
  • 8,207
  • 5
  • 53
  • 78