8

I'm new to AngularJS, so this might be a trivial question.

The problem I'm facing is that the AngularJS bindings {{Object.Field}} reverting to un formatted state whenever there is an update-panel partial update. I understand that the update-panel is replacing the DOM with the non formatted text({{Object.Field}}), but I'm not able to make angular re-evaluate the piece of HTML that was injected by the update panel.

What I've tried so far:

  • Got a handle to the scope of the controller from the End_Request of the update panel and wrapped the update function on the controller inside of a $scope.apply();
  • Called the $scope.compile at the same place and also inside the controller, with no result changes.
  • Tried replacing with a directive, but I don't think this is what I want.

I can get a handle to the DOM inside the controller and change it directly, but I understand that this is not a recommended approach and hence I'm here asking this question.

How do I make angular re-evaluate the piece of HTML, replaced/injected by an asp.net update panel's partial update?

3 Answers 3

15
+200

You need to compile the template again within the End_Request of PageRequestManager. I used a div with an id so I could reference the element of interest within the End_Request function.

The javascript code:

var mod = angular.module("myApp", []);

mod.controller("MainController", function ($scope, $compile) {
    $scope.data = {};
    $scope.data.world = "world";

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
        var elem = angular.element(document.getElementById("angularTemplate"));

        elem.replaceWith($compile(elem)($scope));
        $scope.$apply();
    });
});

The aspx code:

<body ng-app="myApp" ng-controller="MainController">
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <div id="angularTemplate">
                    Hello, {{data.world}}
                </div>

                <asp:Button ID="btnUpdate" runat="server" Text="Update Me" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>

Clicking the "Update Me" button will keep "Hello, world" in the template. The key is to also call $scope.$apply() in the End_Request as this is technically run outside of angular.

Sign up to request clarification or add additional context in comments.

Comments

3

If you have a dynamic content and Angular bindings, this solution might not be enough for you.

I've tried to implement this solution and it almost worked. I saw the HTML content of the directive that inside the .NET application, but all Angular bindings, like ng-repeat and ng-click, didn't work.

I've found the solution here:

http://blog.travisgosselin.com/integrating-angularjs-in-a-tight-spot/

You need to manually initialize your module in the add_endRequest event:

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
                angular.bootstrap($('#myDiv'), ['myNgApp']);
            });

This solution was enough, and I removed the solution with the $compile.

You can read about angular.bootstrap in the documentation: https://docs.angularjs.org/guide/bootstrap

1 Comment

In my case, I used add_pageLoaded rather than add_endRequest so that I could bind Angular on the first page load as well as subsequent refreshes of the UpdatePanel. (Note that when doing this, you should remove the ng-app="MyApp" attribute from your HTML.) Also, some examples in the Angular bootstrap documentation suggest bootstrapping on the document element, but that won't work in most UpdatePanel scenarios because it is not replaced. Instead, you should bootstrap on a child div.
0

These solution are good and well enough explained. But still if some-one is struggling with asp.net Update panel and AngularJs, Here's one shot but unethical solution

First define a global variable in your aspx page

var myTempScope;

Then do this in you document.ready event

$(document).ready(fucntion(){
    myTempScope = angular.element($("#myAngularDiv")).scope() ;
});

and then when you are calling an angular function from your aspx page like

function callAngularFunction() {
    if(angular.element($("#myAngularDiv")).scope() == undefined)
        myTempScope.AngularFunction();
    else
       angular.element($("#myAngularDiv")).scope().AngularFunction();
}

In my case this was working fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.