Search code examples
asp.netangularjsupdatepanel

AngularJS with ASP.NET Updatepanel partial update


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?


Solution

  • 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.