Terminating without building a separate scope

Dynamic Application Use Case

The application I am currently developing is highly dynamic in nature. It adapts to changing inputs based on a template variable, and uses directives to fetch the required templates and construct HTML output accordingly. Each template has associated events, which require the destruction of childScopes to trigger appropriate destroy events when the scope changes. Failure to call the destroy method results in a memory leak.

[edited] To elaborate further, at the core we have a generic widget that displays a button whose value changes with each click, or for visually impaired users, renders a list of radio buttons instead. These buttons act as "hotspots" over an image to evaluate joint pain scores. While visually impaired patients cannot see the buttons, their screen readers can read out the radio inputs. A tablet is used for data capture, passing between researcher, patient, and doctor. There's a toggle button to switch between visual and visually impaired modes for quick comprehension by doctors. Due to spotty hospital WiFi, I utilized Angular to create a single-page application for this purpose.

The process involves passing a template variable into the directive. The link then reads this variable and loads the corresponding cached templates. Upon pressing the button, the template may change, prompting the link to re-read it. However, I encountered a memory leak issue when switching from a slider to a radio list input for visually impaired users using a jQuery slider. The more switches between views, the more memory consumed. But calling the destroy method before $compile resolves the memory leak problem. To avoid destroying everything with scope.$destroy, I implemented a childScope.

This task could be achieved using ng-if or ng-switch based on the template variable, but we chose a programmatic approach since future requirements involve dynamic changes in multiple views such as "doctor view," "researcher view," "patient view," "patient visually impaired view," "elderly view," etc., each with unique appearances and functionalities tailored to specific needs.

Challenge

I'm facing difficulty binding the model to the generated childScope due to $new() creating an isolated scope that struggles to communicate externally. My primary goal is to properly destroy the scope to prevent memory leaks.

My queries are:

  • Is there a way for the childScope to bind with the parent ng-model?
  • Is there an alternative method to trigger destroy?

Code Example

Here is a simplified version of my code focusing on essential components.

Template

<div ng-app="app" ng-controller="ctrl">
    <div>
        <h1>Input</h1>
        <doodad ng-model="foo"></doodad>
        <nested-doodad ng-model="bar"></nested-doodad>
        <nested-doodad ng-model="qux.value"></nested-doodad>
    </div>
    <div>
        <h1>Output</h1>
        <span>{{ foo }}</span>
        <span>{{ bar }}</span>
        <span>{{ qux | json }}</span>
    </div>
</div>

Application

function ctrl($scope) {
    $scope.foo = "foo";
    $scope.bar = "bar";
    $scope.qux = { value : "qux" };
}
angular
  .module('app', [])
  .directive('doodad', function($compile) {
      var linker = function(scope, element) {
          var childScope;

          /* Method to trigger destroy on child widgets */
          var getNewScope = function(oldScope) {
            if (oldScope) {
                oldScope.$destroy();
                oldScope = null;
                element.html('');
            }
            return scope.$new();
          };

          var renderTemplate = function() {
              childScope = getNewScope(childScope);
              /* Template is dynamic - hardcoded for example */
              /* Events & other bindings occur here */
              element.html('<input type="text" ng-model="ngModel" />');
              $compile(element.contents())(childScope);
          }

          scope.$watch('template', renderTemplate);
      }
      return {
          restrict: 'E',
          replace: true,
          require: '^ngModel',
          scope: {
              ngModel : '=',
              template: '='
          },
          link: linker
      }
  })
  .directive('nestedDoodad', function() {
      return {
          restrict: 'E',
          replace: true,
          scope: {
              ngModel : "="
          },
          template: '<div><doodad ng-model="ngModel"></doodad></div>'
      }
  });

JSFiddles

Answer №1

Can the childScope be bound to the parent ng-model in a different way?

$scope = $parent.$scope;

Is there an alternative method to trigger destruction?

angular.element(document).injector().get('$rootElement').removeClass("ng-scope")

References

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

Clicking on React Js reverses an array that had previously been unreversed

My issue involves an array pulled from a database that I have reversed so that the newest entry is displayed at the top when a button is clicked, opening a modal-style window. However, when the array is displayed in the modal window, it appears to be flipp ...

The addClass function in jQuery does not seem to be functioning properly when used within

I've run into an issue with my jQuery addClass function in a loop. It's supposed to turn my Font Awesome star golden, but for some reason, it's not working as expected. The loop itself is functioning properly - I double-checked this by using ...

Using ReactJS to dynamically append tags and content to react-dom and then refresh

As a newcomer to reactJS, I am currently working on building a react app presentation using spectacle. The unique aspect of this project is that the content and number of slides for the presentation are dynamic and fetched from a server. These slides come ...

The data type 'StaticImageData' cannot be converted to type 'string'

I've hit a roadblock with interfaces while working on my NextJS and TypeScript project. I thought I had everything figured out, but I'm encountering an issue with the src prop in my Header component. The error messages I keep receiving are: Typ ...

Unable to physically tap on the checkbox input, though able to perceive the value it holds

When running my protractor test, I encountered an issue with the following statement: await element(by.model('publishCtrl.isPublishedInAllRegions')).click(); The test failed and returned an error message stating "ElementNotVisibleError: element ...

Is MapView in React Native restricted to explicit markers only?

I'm facing a challenging problem while working on my app's mapview. I have been struggling to find a solution for dynamically repopulating the mapview. Initially, I attempted the following approach: render() { const dynamicMarker = (lat, long, ...

Replicate the preceding input data by simply clicking a button

Here is some HTML and jQuery code that I am working with: $(".btn-copy").click(function() { var previousContent = $(this).prev()[0]; previousContent.select(); document.execCommand('copy'); }); <script src="https://cdnjs.cloudflare.com ...

Utilizing AngularJS to target DOM elements within an ng-repeat loop

I currently have my ng-repeat set up within a div tag: <div ng-repeat="x in names"> <h1>{{x.product}}</h1> <h2>{{x.brand}}</h2> <h3>{{x.description}}</h3& ...

Retrieve all the keys from an array of objects that contain values in the form of arrays

Looking for an efficient way to extract all keys from an array of objects whose values are arrays, without any duplicates. I want to achieve this using pure JavaScript, without relying on libraries like lodash or underscore. Any suggestions on how to impro ...

Tips for accessing information from an Angular Resource promise

I am currently facing an issue when trying to read data from an angular promise that was returned. Before, I had the following code: var data = category.get({id:userid}); Later, I realized that the data being returned was an unresolved promise. So, I ma ...

What distinguishes between employing a div versus a canvas element for a three.js display?

While it is commonly believed that three.js requires the HTML5 <canvas> element, I have found success in using a simple <div> by assigning height and width properties and then adding the WebGLRenderer.domElement as its child within the HTML str ...

JavaScript tutorial: Removing and reinserting data from a table

When dealing with my scenario, I only want the user to be able to select list box options that will then append both the values and text to table rows. However, a small issue arises when the user tries to select the same option (an already selected option) ...

Is it possible to store data using kue in a node.js environment?

I am currently working with the kue and node.js framework. Check out kue on GitHub When I create and save a job, the data is stored in my local redis server. var job = queue.create('new_job', { title: 'welcome email for tj' ...

Converting an array of 8-bit unsigned integers into a string without the

Currently, I am working on extracting JSON data from an HTML document stored in a Uint8 array. The process involves converting the array to text and then isolating the JSON within a script tag. To achieve this, I initially converted the array into text fo ...

What steps should I follow to install nodemon on my Windows 10 device?

Currently, I am utilizing the bash console on my Windows 10 system. My goal is to install nodemon using node.js, but when attempting to do so, I encounter this error message: sudo: npm: command not found It's puzzling because I should already have n ...

What could be causing my YouTube code to malfunction with certain playlists?

Check out the first jsfiddle playlist here The Alum Songs Playlist is working perfectly, but unfortunately, the same code is not functioning for another playlist ID. View the second jsfiddle playlist here The Medical Animated Playlist is currently not w ...

Struggling to synchronize animation timing between elements using jquery

When you navigate to an album (for example, Nature because I'm still working on the others) and select one of the images, they all gradually fade out while the selected image appears on the screen. What's actually happening is that the selected i ...

Retrieve the observable value and store it in a variable within my Angular 13 component

Incorporating Angular 13, my service contains the following observable: private _user = new BehaviorSubject<ApplicationUser | null>(null); user$ = this._user.asObservable(); The ApplicationUser model is defined as: export interface ...

Refreshing Yii Dropdown List After Adding a New Item

Here is the code snippet I am working with: <p> <?php echo $form->labelEx($model,'phone_type'); ?> <span class="field"> <?php echo $form->dropDownList($model,'phone_type', CHtml::listData(PhonesT ...

Create a JavaScript variable every few seconds and generate a JSON array of the variable whenever it is updated

My variable, which consists of random numbers generated by mathrandom every second, such as "14323121", needs to be saved to an array for the latest 10 updates. function EveryOneSec() { var numbers = Math.random(); // I want to create an array from th ...