Gimmly
Gimmly

Reputation: 463

Dynamically loaded AngularJs code via ASP MVC are not bound

I'm loading a Partial view which contains AngularJS code, using the code below:

http.post("/Admin/LoadPartial", {
path: "~/Views/Admin/Urchin/Modals/_ChangeHero.cshtml",
model: self.newID
}).then(function (res) {

//res.data is the .cshtml                       
var element = angular.element(res.data);
var modal = $compile(element)(scope);
self.newSlides.push({
    "ID": self.newID,
    "Data": self.newData,
    "Modal": modal.html()
});

scope.$emit("ngRepeatFinished");
Notify.Show("Saul goodman", "notice");});

This is how I render the partial:

<div ng-repeat="item in h.newSlides" 
     ng-bind-html="item.Modal | to_trusted" id="Hey-{{item.ID}}"></div>

And the filter:

    .filter('to_trusted', ['$sce', function ($sce) {
    return function (text) {

        return $sce.trustAsHtml(text);
    };
}])

The problem:

The rendered partial loads as HTML, but it contains code like this:

<button id="bgProg-@Model" class="progress-button" ng-click="h.EditBG()">

where h is the controller that loaded the .cshtml, and no click event is bound to the button.

Any ideas as to where I'm doing things wrong are greatly appreciated.


Progress

Thank you @user1620220 for the response. I added this right after Notify.Show(.. :

timeout(function () {
var what = document.getElementById("Hey-" + self.newID);
var element = angular.element(what);
var modal = $compile(element)(scope);
what.innerHTML = content;}, 0, false);

and still no bindings are happening.

Upvotes: 2

Views: 99

Answers (1)

user1620220
user1620220

Reputation: 1315

You are using $compile to generate a compiled node, but then you are calling html() to convert the node back to a string. ng-bind-html then converts the string into an uncompiled node and adds it to the DOM.

Instead, just pass res.data to ng-bind-html, allow the digest loop to run, then compile the in-situ DOM node.

Edit: After reading your edit, it occurred to me you need to use the cloneAttachFn returned by $compile. Here is my new proposed solution:

HTML:

<div ng-repeat="item in h.newSlides"> 
    <div id="Hey-{{item.ID}}"><!--place holder--></div>
</div>

JS:

var linkFn = $compile(res.data);
timeout(function () {
    self.newSlides.forEach((slide) => {
        var what = document.getElementById("Hey-" + slide.ID);
        linkFn(scope,(clone) => {
            what.parentNode.replaceChild(clone, what);
        });           
    });        
}, 0, false);

Upvotes: 1

Related Questions