3

I am doing my first steps with directives on AngularJS and this directive is not working for me.

I have an ng-repeat list

<ul ng-after-list-filter>
    <li ng-repeat="item in items | filter:activeFilter.filterType = activeFilter.filterValue">...</li>
</ul>

that is being filtered with $scope.activeFilter.filterValue

I am trying to create the ng-after-list-filter directive so it will execute after the list has been filtered so I can make a dom manipulation on that new ul element.

This is my directive that is not working:

myModule.directive('ngAfterListFilter',function(){
    return {
        restrict: 'A',
        link: function(scope,element,attrs) {
            scope.$watch(scope.activeFilter.filterValue, function(val) {
                console.log('do something here');
            });
        }
    }
});
  1. How do I make it work? I assume that scope.activeFilter.filterValue is not being updated, but - it is in the scope, and it does get updated and the list gets filtered. and I am trying to watch on this variable so why isn't it working?

  2. Is there a better way to create this directive? I mean - I want to run a DOM changes when the list get updated (adjust sizes of things). so is there a way to listen to the $('ul').html()? I tried that but it outputs me an error that I put raw text in javascript

1
  • You have only one equals in your filter directive; hopefully that's a typo and you meant ==? Commented Jul 12, 2013 at 22:17

2 Answers 2

7

$last can be used to determine when the last <li> is being created. See this fiddle (I didn't write it) for an implementation of a checkLast directive that you can attach to your <li> element:

directive('checkLast', function () {
  return function (scope, element, attrs) {
     if (scope.$last === true) {
        element.ready(function () {
           // manipulate ul here, or if that doesn't work
           // try with $timeout:
           // $timeout(function() { 
           //    do manip here
           //}, 0, false);  // remove false if you need $apply to run

See also https://stackoverflow.com/a/13906907/215945

I'm not sure if element.ready() is necessary, or if it works on dynamically generated elements.

Sign up to request clarification or add additional context in comments.

Comments

0

It seems like you want to reuse the filtered values from the filter? Correct?

If that's the case all you really need to do is this:

<!-- initial filter -->
<ul ng-after-list-filter>
    <li ng-repeat="item in filteredData =  (items | filter:activeFilter.filterType)">{{item}}</li>
</ul>

<!-- reuse what you filtered -->
<div ng-repeat="item in filteredData">{{item}}</div>

I wish I could take credit for this, but it's a trick I saw in another question on StackOverflow that I can't find now.

Then to know when this has been updated, you'd $watch the filteredData on the scope:

myModule.directive('ngAfterListFilter',function(){
    return {
        restrict: 'A',
        link: function(scope,element,attrs) {
            scope.$watch('filteredData', function(val) {
                console.log('do something here');
            });
        }
    }
});

2 Comments

I don't understand why to duplicate the list? now I have 2 lists instead of one and I still don't know how to trigger a function when the list has finished changing.
Oh, sorry, I didn't understand your question I guess. If you need to know when the list is filtered, you could add a $watch to the filteredData parameter above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.