Angular.js: как передать ngclick из исходного dom в директиву dom?

Привет, у меня есть эта "подтверждающая" директива кнопки, над которой я работаю,

Код html, который выдает директиву "подтверждаемый"

      <span confirmable ng-click='users.splice($index,1)'></span>

директива: (coffeescript)

  angular.module('buttons',[])

  .directive 'confirmable', () ->
    template: """
      <button class='btn btn-mini btn-danger'>
        Destroy
      </button>
    """
    replace: yes

Итак, конечный результат, который я хотел бы увидеть, сгенерированный с помощью этой директивы, -

      <button class='btn btn-mini btn-danger' ng-click='users.splice($index,1)'>
        Destroy
      </button>

До сих пор мне приходилось работать с функцией связывания внутри директивы

  angular.module('buttons',[])

  .directive 'confirmable', () ->
    template: """
      <button class='btn btn-mini btn-danger'>
        Destroy
      </button>
    """
    replace: yes
    link: (scope, el, attrs) ->               <---------- linking function
      $(el).attr 'ng-click', attrs.ngClick

Но я снова просмотрел документацию по директиве и нашел свойство scope с операторами =, @и операторами, но я действительно не уверен, что они нужны мне. Тогда это переводит свойства, которые мне все еще нужно понимать, но на данный момент также не кажется полезным. Поэтому пока моя функция привязки делает трюк, но я подумал, что должен попросить, чтобы angular предоставил более элегантное решение.

Спасибо!

Ответ 1

Мне кажется, что вы хотите вызвать метод из родительской области внутри вашей директивы...

Я собрал Plunk here

(Извините, мне нравится JavaScript... так вот идет)

Здесь вы являетесь родительским контроллером.

app.controller('ParentCtrl', function($scope) {
    $scope.fooCalled = 0;
    $scope.foo = function() {
        $scope.fooCalled++;
    };
});

Затем ваша отметка

<div ng-controller="ParentCtrl">
   Foo Called: {{fooCalled}}<br/>
   <button ng-click="foo()">Call From Parent</button><br/>
   <custom-control custom-click="foo()"></custom-control>
</div>

И ваше объявление директивы:

app.directive('customControl', function(){
   return {
     restrict: 'E',
     scope: {
        innerFoo: '&customClick'
     },
     template: '<button ng-click="innerFoo()">Call From Control</button>'
   };
});

Бит в объявлении scope в определении вашей директивы связан с тем, что связывает ссылку функции родительской области с вашей областью директивы, поэтому ее можно вызвать при нажатии. Это то, что существует &.

Ответ 2

Вы делаете это правильно. Контроллеры предназначены для совместного использования общих функций между директивами; вам здесь не нужен. Также этот случай настолько прост, что вам даже не нужна функция ссылки:

http://jsfiddle.net/V7Kpb/12/

Копирование атрибутов директивы на этапе ссылки не делает ничего, кроме Angular. У вас будет только кнопка с атрибутом ng-click, но она была добавлена ​​после Angular обработала DOM.

Также обратите внимание, element, поскольку вторым параметром функции ссылки уже является jQLite (и предположительно полный jQuery, если у вас тоже есть связанное соединение.) Не нужно jQuerify.

Кроме того, в отношении выделенных областей (=, @, и вы упоминаете). Это прекрасный элегантный синтаксис, но большой недостаток - это любые другие директивы того же элемента, которые также выделяются из области видимости. Поэтому, если вы хотите работать с ngModel, что является обычной практикой, вы не можете использовать область изоляции. Фактически даже в этом случае, если вы используете изолированную область действия ng-click stop, работайте. Потому что он попытается оценить выражение, которое содержит вещи, явно не объявленные в свойстве scope {}.

Ответ 3

Если вы манипулируете DOM на этапе ссылки и хотите добавить логику angular к ее элементу (элементам), ему необходимо скомпилировать обработанные элементы. Пусть angular введите $compile и вызовите его после того, как вы закончили обработку DOM и добавили свои директивы ng-*.

function MyDirective($compile)
{
    return {
        
        restrict: "AE",
        templateUrl: "/path",
        link: (scope, element, attributes) => 
        {
            // Add your directives

            $compile(element.contents())(scope);
        }
    };
}