简体   繁体   中英

ng-click inside ng-repeat doesn't work with :focus and display

Noob web developer here.

I want to know why this fiddle doesn't work. When you click on a link in the dropdown menu, I would expect an alert to appear, but none does. The button labeled 'yell' gives the desired behavior, but it's not a dropdown element.

Javascript

function apiCtrl($scope) {

    $scope.fish = [
        'blum',
        'blum',
        'shub'
    ];

    $scope.yell = function() {
        alert("HEY");
    };
}

HTML

<div ng-controller="apiCtrl">
    <button ng-click='yell()'>yell</button>
    <br>
    <input class='autocompleted' type='text'/>
    <ul>
        <li ng-repeat='f in fish' tabIndex='-1'>
            <a ng-click="$parent.yell()"> {{f}}
            </a>
        </li>
    </ul>
</div>

CSS

input.autocompleted + ul {
  display: none;
}

input.autocompleted:focus + ul {
  padding: 2px;
  margin: 1px;
  list-style-type: none;
  display: block;
  position: absolute;
  z-index: 2;
  background-color: #FFF;
  border: 1px solid #000;
}

I've looked for several solutions, and while there are quite a few, none of them have the added conundrum of inexperienced css mixed in. StackOverflow won't allow me more than two links in one post, so here 's one of the solutions I looked at.

As you can see, I've used $parent to dodge the ngRepeat directive's transclusion.

I tried using $rootScope to create global access to yell() , as another solution suggested. No dice.

Removing the CSS makes it work, but what is it in there that breaks Angular?

In order for click event to execute on an element, mousedown and mouseup event needs to happen on the same element. In your case as the mousedown happens, the css rule input.autocompleted + ul{display: none;} comes into picture as you lose focus from the input, eventually mouseup never happens on that element and no click event executes. You can test this by changing <a ng-click="yell()"> to <a ng-mousedown="yell()"> and you will see the alert happening. Also a typical autocomplete does not show the items on click of the textbox instead generally when you type the characters in the suggestions show up. Possibly when you implement that you should not get into these issues.

Fiddle

On a side note, it would be better to use module.controller('controllerName', constructorWithDep) syntax since global scope controller discovery will be broken (Can opt in though) with version 1.3 .

Another thing to mention that usage of $parent is not a good practice, instead you could use . syntax on the items being bound on the child scope. In your case you don't need that at all since yell is a function defined on its parent scope and is a reference type it will be automatically carried down via prototypical inheritance to its child scope(s).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM