简体   繁体   中英

directives and inter-element communication

I created the following simple directive to redirect enter keypress events.

I think it might be a better to use emit a message to another directive, that handles the keypress event, rather than using a jQuery identifier, as I do here.

Consistent with Angular philosophy, what is best practice when dealing with element to element communication? why?

thanks

=========================================================
.directive('redirectEnter',function() {
    return {
        restrict : 'A',
        link : function($scope,$element,$attr) {
            $element.keypress(function($event) {
                if($event.keyCode == '13') {
                    $($attr.redirectEnter).click();
                    $event.stopPropagation();
                    $event.preventDefault();
                }
            });
        }
    }
})
=========================================================
<a redirect-enter="#apply">Redirect enter example</a>
<button id="apply">Apply</button> 
=========================================================

Your HTML example doesn't have any logic wired to the button element via ng-click , etc., so for the sake of example, let's imagine a view like this:

<input ng-model="model.something">
<button ng-click="submit()">

(Remember, your DOM elements should be tied to logic via directives or a controller's scope. Using $("#apply").click(...) is a no-no!)

In this example, it's easy to say that we want the input element to eat "enter" keypresses and "redirect" them to the button. But what we really want an "enter" keypress in the input to do is the action the button would otherwise perform --in this case, calling the submit method on the scope.

Here is a directive that takes an expression to evaluate as its redirect-enter attribute (I'd probably call it onEnter or something) and evaluates the expression.

<input ng-model="model.something" redirect-enter="submit()">
<button ng-click="submit()">Submit</button>

Here is the directive that makes this work:

app.directive('redirectEnter', function() {
  return {
    restrict : 'A',
    link : function($scope,$element,$attr) {
      $element.keypress(function($event) {
        if($event.keyCode == '13') {
          $scope.$eval($attr.redirectEnter);
          $event.stopPropagation();
          $event.preventDefault();
        }
      });
    }
  }
});

Here is an example on jsFiddle: http://jsfiddle.net/BinaryMuse/HgD9y/

Note that, if you want the same behavior on a link element, you should use ng-click .

If you're struggling with keeping yourself from using plain jQuery selectors in your Angular code (like the no-no I mentioned at the top of this answer), consider this advice from the Angular FAQ :

Stop trying to use jQuery to modify the DOM in controllers. Really. That includes adding elements, removing elements, retrieving their contents, showing and hiding them. Use built-in directives, or write your own where necessary, to do your DOM manipulation. See below about duplicating functionality.

If you're struggling to break the habit, consider removing jQuery from your app. Really. Angular has the $http service and powerful directives that make it almost always unnecessary. Angular's bundled jQLite has a handful of the features most commonly used in writing Angular directives, especially binding to events.

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