Reputation: 53
I have a trouble to get angular working with .Net partial postbacks.
Question is basically same to this : Re-initialize Angular bindings after partial postback
Basically I have a tab on which I have angular app, then I have second tab with some c# control, I have to do partial postback between tabs and when I am going back to my app, there is nothing.
I have tried routing with ngView then I have tried $route.reload()
(it goes to the controller and I can see that the template is being pulled down but the result on the page is none). Then I tried compile(templateCache.get(lazyTableControllerRoute.current.templateUrl))(scope)
as mentioned here. Nothing.
Please help :)
After each postback I am putting on page this html :
LiteralControl lazyControl = new LiteralControl("<div ng-app=\"LazyLoadingApp\" style=\"padding:10px\" ng-controller=\"LazyTableController\" ng-view><lazy-table> </lazy-table></div>");
Controls.Add(lazyControl);
And some config constants like templateUrl
.
Here is my code :
var app = angular.module('LazyLoadingApp', ['ui.bootstrap', 'ngRoute'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
app.config(function ($routeProvider, $locationProvider, tableTemplateUrl) {
$routeProvider.when('/Page.Web.UI/sptl_project.aspx', {
controller: 'LazyTableController',
templateUrl: tableTemplateUrl,
});
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
});
//**This objects I am using after partial postback to check in the console if e.g. $route.reload() works..**
var lazyTableControllerRoute = null;
var templateCache = null;
var compile = null;
var scope = null;
app.directive('lazyTable', ['tableTemplateUrl',
function (tableTemplateUrl) {
return {
name: 'lazyTable',
priority: 0,
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: tableTemplateUrl
};
}
]).controller('LazyTableController', ['$scope', '$rootScope', 'lazyFactory', 'opsPerRequest', 'header', '$route', '$templateCache', '$compile',
function ($scope, $rootScope, lazyFactory, opsPerRequest, header, $route, $templateCache, $compile) {
lazyTableControllerRoute = $route;
var loadingPromise = null;
templateCache = $templateCache;
compile = $compile;
scope = $scope;
(...) rest is not important
UPDATE:
I was trying with require.js.. (Again, it's working after full page load.) My idea was to bootstrap element after partial postback. I built simple test case that in Update Panel along with my app there is simple button, just making partial postback. After click (when app disappeared) I tried in console:
angular.bootstrap(document, ['LazyLoadingApp'])
But then I got error which I cannot remove:
App Already Bootstrapped with this Element 'document'
Here is plunker for app in require.js way (but please keep in mind that it's just for code review purpose..)
Upvotes: 5
Views: 1873
Reputation: 160
Though the other answers probably do work I've found that best course of action is to try to not be in a 'mixed' state of .net controls and angular controls that depend on interaction between the two.
The process for this is undocumented at best... and you end up writing a lot of code to accommodate simple things.
I wouldn't recommend doing the following for long and only suggest it as a temporary/transitional solution and I know this may not solve every case .... but note you can always attack this problem from the dot.net side as follows and redirect back to the page you are on...
protected void cbChecked_My_DotNet_CallBack(object sender, EventArgs e)
{
DoDotNetStuff();
if(NeedToSignalToAngular){
response.redirect(yourpage.aspx?yourparams=xxx)
}
}
Upvotes: 0
Reputation: 53
Alright ! Problem solved.. So in order to work with partial postbacks you need to :
Define app like this: (remember that you have to remove ng-app from html !)
<base href="/">
<asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="fire" runat="server" Text="fire!" />
<div id="parent" > <div id="boodstapped" ng-view ></div></div>
</ContentTemplate>
</asp:UpdatePanel>
Instantiate app like this:
var app = angular.module('LazyLoadingApp', ['ui.bootstrap', 'ngRoute']);
jQuery(document).ready(function ($) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
function EndRequestHandler(sender, args) {
jQuery('#parent').children().remove();
jQuery('#parent').append('<div id="boodstapped" ng-view ></div>');
angular.bootstrap(jQuery('#boodstapped'), ['LazyLoadingApp']);
}
prm.add_endRequest(EndRequestHandler);
});
Then when you will try to do partial postback EndRequestHandler will bootstrap app again. What's important to remove previously bootstrap element, to avoid angular "already bootstrapped" error.
Click Here for more information.
Upvotes: 0
Reputation: 991
ngtutorial.com/learn/bootstrap
Upvotes: 0