I need to show an alert after a route has been loaded by angularjs. The piece of code to show the alert is in the view loaded asynchronously by angularjs:
<script>
alert('test');
</script>
Once the view has loaded, I expect this to be run, but it does not. I know I can broadcast and tell it to run afterwards etc, but I need a more generic solution.
Assuming you are talking about route changes based upon ngRoute internal to an angular SPA
Inject $route into your controller:
.controller('MyCtrl', function($scope, $route){});
and in your controller you subscribe to the event of the route changing:
$scope.$on('$routeChangeSuccess', function() {
alert('test'); // <-- alert from the question
});
There is one more option to run javascript function use ngInit
<div ng-init="initialize()"></div>
call the function which is inside the controller
app.controller('myController', function($scope){
$scope.initialize = function () {
alert("Page loading just completed");
}
});
Related
I've working on a project that uses AJAX to load content, and would like to load a bit of content that will be developed using AngularJS. After I load the content in via AJAX, it just sits there -- Angular doesn't recognize the angular directives I've added. How do I get AngularJS to scan the new code and process it?
var ajaxLoad = function(obj){
$('.target').load('dynamiclyDeterminedHTMLTarget',function(response, status, xhr){
//Target HTML is loaded, but not parsed by Angular
});
}
Edit:
For complete clarity, I'm actually loading the angular content inside this call. The controller is inside the ajax content. See below.
<div class='ajax-loaded-content'>
<div ng-controller='MyNewCtrl'>
{{ this_should_be_compiled_but_isn't }}
</div>
</div>
I'm working on a 'legacy' project that doesn't use angular, and I'm trying to inject angular into it because that -- to me -- makes the most sense.
After receiving an HTML response via AJAX, use the $compile service to compile/link the template against some scope.
app.controller('TestCtrl', ['$scope', '$compile', '$element', '$http',
function ($scope, $compile, $element, $http) {
$http.get('dynamiclyDeterminedHTMLTarget').then(function (res) {
// inject the DOM content
$element.html(res.data);
// compile/link element contents
$compile($element.contents())($scope);
});
}
]);
Alternatively, you can hand off the AJAX request to the ngInclude directive, which will take care of loading, compiling, linking, and injecting the content into the DOM.
<div ng-include="dynamicallyDeterminedHTMLTarget"></div>
<!-- (provided the scope has a "dynamicallyDeterminedHTMLTarget" property) -->
If you initiate the request outside of the Angular lifecycle, you can bootstrap the dynamic content as a stand-alone Angular app.
$('#target').load('dynamicallyDeterminedHTMLTarget', function() {
angular.bootstrap(this, ['myApp']);
});
I have a simple modal that appears when the user enters a page, but it is creating two of them. I have looked through the app and there are not two calls to the modal.
Here is the controller for it:
angular.module('rokoApp')
.controller('FinanceCtrl', function($scope, $modal) {
$modal.open({
templateUrl: 'includes/modal.html',
controller: function ModalInstanceCtrl($scope, $modal,$modalInstance){
console.log('opened')
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
will be much better if you give us an example of functional code in plunker or jsfiddle, because the problem could be in another place.
For example:
When we started creating an app with AngularJS usually we put ng-controller in a upper tag and write the first lines of our app. The problem is that some times when we added routing we forget remove the ng-controller and then the controller is executing twice. The first time with the configuration of the module and again with the processing of the html.
So the solution here is to remove the tag in the html if we use routing or delete the controller property of routing and keep the ng-controller in the html.
I will let you the two codes:
With the error: http://plnkr.co/edit/TmQ5QhjD55WTurQNaEIv
Without the error: http://plnkr.co/edit/1xGUGEvAZ6jUBs8CbhTT
I've just started using Onsen UI by implementing the bootstrap example and I've been trying to get the view to update when I change the page attribute.
<body ng-controller="PageLoadingCtrl">
<ons-screen page="{{loadedPage}}"></ons-screen>
</body>
My controller's code:
app.controller('PageLoadingCtrl', ['$scope', '$timeout', 'notificationService',
function($scope, $timeout, sharedService){
$scope.loadedPage = "index.html";
$scope.updatePage = function(page){
$timeout( function (){
$scope.loadedPage = page;
$scope.$apply();
}, 500);
};
$scope.$on('changePage', function (event, message){
$scope.updatePage(message);
});
}
]);
As you can see I'm using a controller on the body object so that I can update the loadedPage variable however, when I fire the changePage event, the view doesn't change.
After checking the DOM elements with web inspector I can see that page attribute is equal to whatever I pass to the updatePage function.
So far I tried to force a refresh with $apply and $digest but that still doesn't do the trick.
Cheers!
Because ons-screen need to maintain page stack. it's not intuitive to use binding for the page attribute.
Using ons.screen.presentPage()/dismissPage()/resetPage() is the preferred way.
http://plnkr.co/edit/GRVZl35D1cuWz1kzXZfF?p=preview
In the custom fancybox (aka lightbox, a dialog) I show contents with interpolated values.
in the service, in the "open" fancybox method, i do
open: function(html, $scope) {
var el = angular.element(html);
$compile(el)($scope); // how to know when the $compile is over?
$.fancybox.open(el); // the uncompiled is shown before the compiled
}
The problem is that the content in the dialog is loaded before the end of the $compile, so after less than a second i got a refresh of the dialog content with the values.
The plunkr works, but i want to avoid that the "el" is shown before it gets totally compiled: i want to show it only after the $compile has finished his job
Is there a way to know when the $compile it's over so i'll show the content on fancybox only after that?
You can't inject $scope into services, there is nothing like a singleton $scope.
So instead of $compile(el)($scope); try:
var compiledEl = $compile(el);
....
The $compile returns compiled data.
as a side note
I would provide service to directive and compile it into directive instead. I think it's the right way.
I've had the same problem with the ngDialog modals and popup provider. I needed to position the dialog based on its height. But the height depended on the compiled DOM.
I eventually found a solution using $timeout, like described in that post: http://blog.brunoscopelliti.com/run-a-directive-after-the-dom-has-finished-rendering/
For your code, it would give something like that:
open: function(html, $scope) {
var el = angular.element(html);
$compile(el)($scope);
$timeout(function() {
$.fancybox.open(el);
}, 0);
}
$viewContentLoaded never fires in my Angular controller. The following:
function MyController($scope)
{
$scope.$on('$viewContentLoaded', function()
{
alert("blah");
});
}
Never hits a breakpoint, and never pops up the alert. I think this is pretty standard use, so I'm not sure what it could be, but it's definitely not firing. Everything else in the controller is behaving properly.
What would cause this?
Try this instead:
function MyController($scope)
{
$scope.$watch('$viewContentLoaded', function()
{
alert("blah");
});
}
Base on your comment above, it sounds like you have something like this:
<ng-view>
<div ng-controller="MyController"></div>
</ng-view>
I'm not sure what content in the ng-view tag will do, but the $viewContentLoaded is emitted from the ng-view scope. This means, it only goes up from the ng-view and thus your controller would never catch it.
I solved this by specifying the controller in the app.js route provider rather than using ng-controller in a div in the view. I only use this method if I need to use $viewContentLoaded, otherwise I use ng-controller.
angular.module('myapp', [...])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/MyRoute', {templateUrl: 'views/MyView.html', controller: MyController})
});