AngularJS: $viewContentLoaded fired before partial view appears

前端 未结 3 2030
面向向阳花
面向向阳花 2020-12-03 01:16

For a partial view I want to do some JavaScript stuff that I usually would do with $(document).ready(function() {...}), e.g. bind venet listeners to elements. I

相关标签:
3条回答
  • 2020-12-03 01:48

    I have solved this issue with the help of Directives. Add one direcitve to your element (like <div my-dir></div>) and do manipulations to the element in respective directive as follows,

    app.directive('myDir', function () {
        return {
            restrict: 'A',
            link: function (scope, element) {
               // Do manipulations here with the help of element parameter
            }
        };
    });
    

    I have also tried state provider events like $stateChangeSuccess, $viewContentLoaded but couldn't solve the issue. Because after those events got fired, it's taking time to render on the DOM.

    So, we can follow this approach which gives perfect results and proper way to implement in Angular JS :)

    0 讨论(0)
  • 2020-12-03 01:57

    This is related to angular digest cycle, it's about how angular works underneath the hood, data binding etc. There are great tutorials explaining this.

    To solve your problem, use $timeout, it will make the code execute on the next cycle, whem the ng-if was already parsed:

    app.controller('LoginController', function ($scope, $timeout) {
        $scope.$on('$viewContentLoaded', function(event) {
          $timeout(function() {
            $scope.formData.value = document.getElementById("loginForm").id;
          },0);
        });
    });
    

    Fixed demo here: http://codepen.io/anon/pen/JoYPdv

    But I strongly advise you to use directives do any DOM manipulation, the controller isn't for that. Here is a example of how do this: Easy dom manipulation in AngularJS - click a button, then set focus to an input element

    0 讨论(0)
  • 2020-12-03 01:57

    This is an answer to Hades a bit late but might help someone else. I setup a service which I will later be able to call from a controller or directive.

    'use strict';
    
    app.factory('viewContentLoaded', function($q, $rootScope, $timeout) {
        var viewContentLoaded = $q.defer(),
            
            foo = function() {
                $timeout(function() {
                    viewContentLoaded.resolve();
                    // Get all entries
                }, 100);//Timeout
            },
    
            checkViewContenLoadedListner = $rootScope.$on('$viewContentLoaded', foo);//Rootscope
    
        return {
            getLoaded: function() {      
                return viewContentLoaded.promise;
            },
            removeViewContenListner: function() {
                //Remove event listern on $viewContentLoaded no $off so call it will unsubscribe it
                //$rootScope.$off('$viewContentLoaded', foo);//Rootscope
                //Don't forget to unsubscribe later
                checkViewContenLoadedListner();
            }
    
        };
    });

    In the controller or directive include viewContentLoaded and call the get function with the promise. Don't forget to change the app to whatever you app name is and include the service file to be loaded.

    viewContentLoaded.getLoaded().then(function(){
        //Remove Listner when done
        viewContentLoaded.removeViewContenListner();
        //Your code to run       
    
    }, function(reason) {
        //$log.error(reason);
    });

    0 讨论(0)
提交回复
热议问题