AngularJS: Preventing controllers from registering multiple times while changing states using UI Router

After injecting HTML with a ui-view into the DOM and changing state using ui.router, I noticed that the controller gets registered multiple times whenever the state is changed. This results in the code executing multiple times, as demonstrated in the Plunker link below. Simply open the console and click back and forth between the left and right buttons to see the controllers executing an additional time for each click.

The issue only occurs when the ui-views are injected into the DOM, not when they live on the index.html as static content.

var app = angular.module('app', ["ui.router", "appHome", "appOther"]).config([
             "$urlRouterProvider", "$stateProvider", "$locationProvider", 
    function ($urlRouterProvider,   $stateProvider,   $locationProvider) {

        $stateProvider.state('appHome', {
            url: '/home/index',
            views: {
                "Alerts": {
                    template: 'THINGS',
                    controller: "AlertsController as Alerts",
                }
            }
        }).state('appOther', {
            url: '/other/index',
            views: {
                "Other": {
                    template: 'THINGS',
                    controller: "OtherController as Other",
                }
            }
        });

    }
]);

Check out the testcase on Plunker here: http://plnkr.co/edit/M2wzVLSSgZ7naOi58qgL

Answer №1

Almost at your destination. I am not criticizing or questioning this method, just offering a solution. Take a look at this live example.

You've successfully established a new scope. Well done. However, that is only part A. The crucial piece B is missing. B - the opposite of A === destroying the old scope (once finished).

This code snippet will help accomplish the task:

 app.controller('MenuController', ["$scope","$compile", "$state","$http",
    function MenuController($scope,$compile, $state, $http) {
        $scope.goToUrl = function (view) {

                // was scope previously created
                var hasPreviousChildScope = this.childScope !== void 0
                                         && this.childScope !== null;

                if(hasPreviousChildScope)
                {
                  // we must clear after ourselves
                  this.childScope.$destroy();
                  this.childScope = null;
                }

                // create new scope
                this.childScope = $scope.$new();

                var html;
                var state;
                if(view == 'Alerts'){
                  view = '<div ui-view="Alerts"></div>';
                  state  = 'appHome'
                }
                else{
                  view = '<div ui-view="Other"></div>';
                  state  = 'appOther'
                }
                $('#test').html($compile(view)(this.childScope));
                $state.go(state);

        };
    }
]);

See it all in action here

Answer №2

Why make things so complex? Is there a particular reason for utilizing this approach?

if(view == 'Alerts'){
   view = '<div ui-view="Alerts"></div>';
   state  = 'appHome'
}
else{
   view = '<div ui-view="Other"></div>';
   state  = 'appOther'
   }

$('#test').html($compile(view)(scope));
$state.go(state);

Isn't there an easier way to achieve the same result, like:

<div ng-controller="MenuController">
   <button ui-sref="appHome" value="Click Me">GoTo Alerts</button>
   <button ui-sref="appOther" value="Click Me">GoTo Other</button>
</div>
<section ui-view></section>

I utilized ui-sref for seamless state navigation. I've created a demo to showcase this. Take a look here. Would that simplify things for you? Is it practical? With this, you might not even need the menuController.

If you require multiple named views (nested views), refer to the documentation. It's well-explained. You could end up with something like:

<!-- index.html -->
<body>
  <div ui-view="alerts"></div>
  <div ui-view="other"></div>
</body>

$stateProvider
  .state('report', {
    views: {
      'alerts': { ... templates and/or controllers ... },
      'other': {},
    }
  })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When using ng-repeat with directives, only the final element will react to resize events

I am encountering an issue with a simple directive that is meant to adjust its width based on the $window.onresize event. Strangely, only the final element/directive in the ng-repeat array is responsive and updates its css as expected. <!-- html --> ...

Only a single button stands between two choices

Currently, I am facing an issue where I have to click twice to perform a search with the correct text. Is there a way for me to track what I'm sending and update it accordingly? Are there any alternative solutions available? Greetings! I have two ra ...

I'm struggling to make this background show up in a div

Anyone able to help me figure this out? I can't seem to get the achtergrond_homepage.png as a background in rounded corners. Edit: It seems like the gray color is always on top. Could it be controlled in the JavaScript part? This is the CSS: @ch ...

Execute a PHP SQL query when a link is clicked

To trigger a SQL query when a link is clicked, I have implemented the following code: mainpage.php: function deleteImage1() { $.post("delete_image.php", { num:1, id:<?php echo $id; ?> }, function(data,status){ alert("Data: " + data + "\n ...

Creating dynamic data for Chart.js to display values

I am attempting to utilize dynamic data using ajax, but my current implementation is not functioning correctly. The ajax response returns data in JSON format via PHP. Here is the code snippet: success: function (result) { result = JSON.parse(r ...

Exploring the functionality of uiRouter using the requirejs framework

I've been struggling with a problem for a while now and haven't found any solutions in other posts related to testing uiRouter with requirejs. I have a basic controller set up that uses $state.go to switch states when a button is clicked. runsCo ...

Retrieve the structure from a React application

When it comes to documenting architecture, the process can be incredibly beneficial but also quite time-consuming and prone to becoming outdated quickly. I have come across tools like Doxygen that are able to extract architectural details such as dependen ...

Retrieve the values and IDs for every span element within the form

I have been attempting to retrieve all span elements within a form and make them editable input text fields. Once you click away, they should revert back to span elements. I will provide a live example in the attached fiddle. I tried my hand at it, but the ...

The Three.js environment experiences lag and a decrease in performance

In the threejs scene, there is a sphere geometry and a plane geometry. The sphere is textured with an image, while the plane geometry is textured with 2D text. The plane geometry is also attached with a click event. When clicking on the plane geometry, ...

What is the method for deactivating an underlying element to prevent it from being clicked on?

I have a situation where I have two elements stacked on top of each other. When I click a button in the first element, the second element opens on top of it. What I am trying to achieve is to make the underlying element non-interactive while the overlaying ...

What is the method for altering the appearance of grid columns with javascript?

What modifications do I need to make in JTML and Javascript? var opac; function checkfun() { opac=(Array.from(document.querySelectorAll('input[type="checkbox"]')) .filter((checkbox)=>checkbo ...

Achieving a multiline ellipsis (clamp) across various levels of HTML tags, compatible with popular browsers like IE and Firefox

After conducting extensive research, I finally discovered a reliable method for implementing multiple Line Ellipsis (using JS, as plain CSS is not effective). Despite exploring 100 different Google results and Q/As, this is currently the only solution that ...

Printing a list of values from a C# page to the presentation layer (ASPX)

I am dealing with a list object in my Cs page that has 2 rows. So, how can I access it separately on my Aspx page? For instance, for a single value, the code would look like this: $("#txtBilldate").val(data.d.lphBillDate); But how can I retrieve a list ...

Using EMCC and WASM on the web, what is the best way to utilize a C function?

I am currently working on a basic website that showcases the outcome of a function call from a javascript file that interacts with a WASM file. Here are the files I have set up: Makefile FILES = add.c OUTPUT = MyWasmLib CC = emcc EMCC_VERSION := $(shell c ...

Cannot use React's setState function

This element represents the main container: modifyData(){ this.setState({ modified: true }).bind(this) } I am passing it to a sub-element: <Profile updateData={this.modifyData} auth={this.props.auth} details={profile}/> The sub ...

Acquire feedback from PHP using SweetAlert notifications

I need to update my HTML form to function like this: <script> function getName() { var name = $('#name').val(); var url_send = 'send.php'; $.ajax({ url: url_send, data: 'name=' + name, ...

Exploring the intricacies of Bower and enhancing dependency management

Currently, I am working on developing a project named myapp using angularJS along with Yeoman Generator. This project involves utilizing Bower to manage dependencies and Grunt to wiredep those dependencies into the index.html file (which essentially genera ...

Utilizing either jQuery or Angular, implement a function that adds line breaks after every x characters within

Is there a way to automatically insert a line break every 10 characters in my code? Here is what I have tried so far: Here is the HTML: <div ng-app=""> <textarea id="chat" ng-model="msg"></textarea> <span class="msg" ng-bind="msg" ...

What mistake am I making with arrays?

My understanding of JavaScript and Node.JS is still developing, so I'm puzzled as to why I'm receiving NaN when using this expression: var aUsersBetted = {}; aUsersBetted['1337'] += 200000; logger.debug(aUsersBetted['1337']); ...

What does the curly braces {} signify in the JavaScript programming language

While delving into sample code, I came across a line that left me puzzled. var foo = {}; From my observations, it seems like this is being used as a type of array where the index is a string provided by the user instead of traditional numerical indexes. ...