2

I'm trying to use AngularJS within an ASP UpdatePanel, very much like in this question: AngularJS with ASP.NET Updatepanel partial update

That solution also helped a lot, at least regarding the static parts, ie everything showed upon initialization.

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
                var elem = angular.element(document.getElementById("myDiv"));
                var newElem = $compile(elem)($scope);
                $scope.$apply();
                elem.replaceWith(newElem.html());
            });

Properties setup within add_endRequest() are shown properly. My problem is that all interaction is dead.

For example if I put

<div id="myDiv">
    {{testtext}}
    <div ng-init="testtext='hello world'"/>
</div>

it'll print out the string as expected. But when adding ie a click event nothing happens.

<div ng-click="testtext='hello world'">Click here</div>

Any ideas why? As I understand it the angular $compile and $scope.$apply() should apply to all angularjs functionality, but it seems not.

2
  • Angular is great for Single Page Applications or client-heavy sites. UpdatePanels are used to avoid doing work on the client side. They're very different paradigms that don't mix well. Have you thought about removing the UpdatePanel and going with an AJAX and Web API based approach? I think that's going to save you a lot of trouble in the long run. Commented Jan 30, 2015 at 15:38
  • Hear hear. You've definitely have a point. Lots of threads here advise not to use Angular at all in a WebForms site, but we already do that here successfully. With UpdatePanels though, as you say, it really requires altering Angular and use it far from how it's intended. I have thought about changing the setup, but nevertheless, sometimes there are reasons to keep the current setup, eg if the cost of switching approach is too high, and then a bit of hacks might come in handy. Commented Feb 2, 2015 at 9:48

2 Answers 2

2

Figured it out with a little help from my friends. The problem was that only the element with my AngularJS list <div id="myDiv"> was recompiled in the add_endRequest() method. When changing this to the div holding the angularjs controller, surrounding the entire UpdatePanel section...

<div ng-controller="UpdatePanelController" id="UpdatePanelController">
    <asp:UpdatePanel ID="UpdatePanel" UpdateMode="Conditional" runat="server">
        ...
    </asp:UpdatePanel>  
</div>

and then compiling its children...

    OneViewApp.controller("UpdatePanelController", function ($scope, $compile) {            
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function () {
            var elem = angular.element(document.getElementById("UpdatePanelController"));
            $compile(elem.children())($scope);
            $scope.$apply();
        });
    });

everything worked fine. Since UpdatePanel replaces the html, the entire controller needs to be recompiled in order for it to work properly.

This can of course also be achieved by (re)bootstraping the angular app for every step, as suggested in another answer, but the above solution is closer to the original code and thus simpler in this case.

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

Comments

1

I had the same issue.

I have an Angular page that have an iframe, that contains an old asp.net application (with user controls and an update panel).

I've tried to add an Angular directive to the .NET part, and had the same issue. The directive had an empty template (no HTML content under the directive's div).

And after applying the solution you've mentioned:

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
            var elem = angular.element(document.getElementById("myDiv"));
            var newElem = $compile(elem)($scope);
            $scope.$apply();
            elem.replaceWith(newElem.html());
        });

I saw the html content but without Angular bindings, like ng-repeat or ng-click.

The solution was found 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 that you've mentioned with the $compile.

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

1 Comment

This approach somewhat contradicts the basic philosophy and simplicity of angularjs. Nevertheless it's what I asked for, and does indeed solve the problem. In my project though it does bring along other structural problems, ie you cannot setup the angular app (which in my case is used on several different pages) in the master page anymore. Will have to do some more thinking here, but thanks for your solution!

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.