Achieve full implementation of ng-repeat within an angular directive

Can you explain how the custom angular directive 'myscroll' is able to detect and interact with the ng-repeat elements that are dynamically created in the code snippet below?

<myscroll>
     <div ng-repeat="item in items">{{item}}</div>
</myscroll>

I've noticed that the $last event doesn't trigger in the parent directive, do you have any suggestions on how to address this issue?

myapp.directive("myscroll", function () {
    return{
        restrict: "E",
        transclude: true,
        template: "<span class='left'></span><div class='mask' ng-transclude></div><span class='right'></span>",
        link: function (scope, element, attr) {

            scope.$watch("$last",function(){ console.log("ng-repeat rendered") })

        }
    }
})

Answer №1

If you want a straightforward approach, consider creating a custom directive called 'repeat-done' to be used alongside the 'ng-repeat' directive. This way, you can easily pass any necessary information to the parent scope of the 'myscroll' directive.

<myscroll>
     <div ng-repeat="item in items" repeat-done>{{item}}</div>
</myscroll>

myapp.directive('repeatDone', [function () {
  return {
    restrict: 'A',
     link: function (scope, element, iAttrs) {

          var parentScope = element.parent().scope();

          if (scope.$last){
               // The ng-repeat iteration is complete and now you can interact with the 'myscroll' scope
               console.log(parentScope);   
          }
        }
      };
    }])

Answer №2

For those who come across this question, I wanted to share the approach I took to solve it. While dluz's answer was helpful, I decided to take a more 'elegant' route.

My task involved using ng-repeat to populate options in a select dropdown and dealing with the incompatibility of ng-options with the jQuery Chosen plugin (a fantastic autocomplete/search dropdown plugin). I needed to initialize the plugin after all options had been rendered.

Here is the HTML snippet:

<select auto-complete ng-model="stuff">
    <option ng-repeat="item in items" value="{{ item.value }}">{{ item.name }}</option>
</select>

And here is the JavaScript code:

// Extension of built-in ngRepeat directive - broadcasts to its parent when it is finished.
// Passes the last element rendered as an event parameter.
app.directive('ngRepeat', function () {
    return {
        restrict: 'A',
        link: function ($scope, $elem, $attrs) {
            if ($scope.$last)
                $scope.$parent.$broadcast('event:repeat-done', $elem);
        }
    };
});

// Directive for working with the Chosen plugin.
app.directive('autoComplete', function () {
    return {
        restrict: 'A',
        link: function ($scope, $elem, $attrs) {
            $scope.$on('event:repeat-done', function () {
                setTimeout(function () {
                    if (!$elem.children(':first-child').is('[disabled]'))
                        $elem.prepend('<option disabled="disabled"></option>');
                    $elem.chosen({ disable_search_threshold: 10, width: '100%' });
                    $elem.trigger('chosen:updated');
                });
            });
        }
    };
});

By extending the ng-repeat directive and adding my broadcaster function, I could easily detect when the ng-repeat operation was complete. This non-invasive addition can be applied universally to ng-repeat instances.

In the function itself, I used Angular's $scope.$parent instead of $elem.parent().scope() to access the parent context. This allowed me to broadcast a custom event (event:repeat-done) and pass the last rendered element to the parent scope.

Subsequently, I could listen for this event in my auto-complete directive and initialize the Chosen plugin on the fully-rendered select element!

This technique can be adapted for any situation where you need to detect the completion of an ng-repeat directive. For example:

myapp.directive("myscroll", function () {
    return{
        restrict: "E",
        transclude: true,
        template: "<span class='left'></span><div class='mask' ng-transclude></div><span class='right'></span>",
        link: function (scope, element, attr) {
            scope.$on("event:repeat-done",function(){ console.log("ng-repeat rendered") })
        }
    }
})

EDIT: In some cases, detecting these events at the rootScope level may be useful. If so, you can replace $scope.$parent.$broadcast with $scope.$emit to allow the event to bubble up rather than down.

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

Using http-proxy to forward request to a different port

In my code, I am creating a proxy that routes all application calls from port 3000 to port 3002 seamlessly. var http = require('http'), httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer(); http.create ...

How React Utilizes Json Arrays to Add Data to a File Tree Multiple Times

For some reason, when attempting to add data to a file tree, it seems to duplicate the data sets. I'm not entirely sure why this is happening. Here's an example of the simple json array I am working with: export const treeDataFile = [{ type: & ...

What could be preventing $routeChangeSuccess from being called?

I have been working on a similar feature for my app, but I'm struggling to capture the routeChangeSuccess event. var myapp = angular.module('myapp', ["ui.router", "ngRoute"]); myapp.controller("home.RootController", function($rootScope, ...

Choosing an option in Angular with ng-model simplified

My query involves using the ng-options to create a select list with data in the following format: data.dateList.day = [{"id":1,"value":1},{"id":2,"value":2},{"id":3,"value":3},...] Can someone guide me on how to select an option with a value of 2 using ...

Leveraging Ajax and jQuery to create a POST request for adding a new record to a MySQL table within a Node.js server

My form is designed to collect user information like name, age, and more. The aim is to submit this data from the client side, inserting it into a MySQL table row. However, I'm facing difficulties in getting the data to successfully insert. Below are ...

Connecting an object to a directive's bindToController

Below is the code for a directive I have created .directive('showMessage',[function(){ return{ scope:true, restrict:'E', bindToController:{ sprop:"=" }, templateUrl:'Communic ...

PHP code for printing a JavaScript string containing a single quote

I'm encountering an issue with a script generated by PHP. When there is a single quote in the description, it throws a JavaScript error and considers the string terminated prematurely. print "<script type=\"text/javascript\">\n ...

"Concealed beneath the text is the link to return to the

I have implemented a back to top link in my MVC project. Layout: <a id="back-to-top" href="#" class="btn btn-primary btn-lg back-to-top" role="button" title="Click to return to the top of the page" data-toggle="tooltip" data-placement="left"><spa ...

Compel a customer to invoke a particular function

Is there a way to ensure that the build method is always called by the client at the end of the command chain? const foo = new Foo(); foo.bar().a() // I need to guarantee that the `build` method is invoked. Check out the following code snippet: interface ...

PHP function - retrieving the beginning element in the array that is returned for every row

My current database setup involves a MySQL DB with approximately 100 rows. Within each row, there is a list of items stored in a column within the table. The challenge I am facing is extracting the first item from this list in each row. For example, if the ...

Jest does not recognize AnimationEvent as a defined element

I am currently facing an issue while attempting to simulate an animationEvent for a test within my Angular application. The error message I receive is: ReferenceError: AnimationEvent is not defined. Given that this feature is experimental, it seems like ...

How can I retrieve the values of jQuery select2 tag list in ASP.NET?

I am looking to retrieve the selected values from the jQuery Select2 plugin in my ASP.NET code behind. Below is a snippet of my code: Client Side: <select id="ddlcountry" runat="server" class="select" style="width: 100%;"> ...

Best practice for stopping routing in angular

I am currently working on an angular application that includes guest functionality. This feature allows me to create a guest account for all unauthorized users in the background. I need to pause routing until the guest account is created and then specify a ...

Issue with Firefox browser: Arrow keys do not function properly for input tags in Twitter Bootstrap drop down menu

Requirement I need to include a login form inside the dropdown menu with username and password fields. Everything is working fine, except for one issue: Issue When typing, I am unable to use the arrow keys (up/down) in Firefox. This functionality works ...

Transforming an older React website with react-helmet-async

I am working on a React site that is client-side rendered and I want to use the react-helmet-async module (version 1.0.7). Here's my scenario in the React app: /public/index.js: <head> <title>My title in the index file</title> ...

Determining if a field in Angular is empty

I'm new to Angular and have a question about handling input fields. I want an action to occur only if the field contains valid content. Currently, I am instantiating a variable, assigning it to the input, and performing a boolean check in an if state ...

Incorporating Google Material Icons into Your UWP Application

I am currently in the process of developing a JavaScript based UWP app for the Windows Store. I've been transferring code from Angular 2 used in my web app directly into the UWP app. However, I've hit a roadblock as none of the material icons I&a ...

Give a class to the element contained within an anchor tag

One way to add a class to the <a>-tag is through this line of code. $("a[href*='" + location.pathname + "']").addClass("active"); However, I am looking to add the class to an li element inside the <a>-tag. What would be the best ap ...

What is the process for adjusting the port used by the npm run watch command?

Currently, when I run npm run watch, the development server is redirecting to http://localhost:3000 instead of http://localhost:8080. Is there a way to change the port from 3000 to 8080? I need to use Tomcat on port 8080. [BS] Proxying: http://localhos ...

What is the recommended approach for running a Node.js application in a production environment on a Windows operating system?

I am currently working on a Node.js application that needs to run on a Windows Server. During development, we usually start the app by running a command in either the command-line or PowerShell: node index.js What is the most efficient and recommended way ...