AngularJS - функция перехода к директиве

У меня есть пример angularJS

<div ng-controller="testCtrl">

<test color1="color1" updateFn="updateFn()"></test>
</div>
 <script>
  angular.module('dr', [])
.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function() {
        alert('123');
    }
})
.directive('test', function() {
    return {
        restrict: 'E',
        scope: {color1: '=',
                updateFn: '&'},
        template: "<button ng-click='updateFn()'>Click</button>",
        replace: true,
        link: function(scope, elm, attrs) { 
        }
    }
});

</script>
</body>

</html>

Я хочу, чтобы при нажатии кнопки появится окно предупреждения, но ничего не отображается.

Кто-нибудь может мне помочь?

Ответ 1

Чтобы вызвать функцию контроллера в родительской области из внутренней директивы области выделения, используйте имена атрибутов dash-separated в HTML, как указано в OP.

Также, если вы хотите отправить параметр своей функции, вызовите функцию, передав объект:

<test color1="color1" update-fn="updateFn(msg)"></test>

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='updateFn({msg : \"Hello World!\"})'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {             
        }
    }
});

Fiddle

Ответ 2

Возможно, мне что-то не хватает, но хотя другие решения вызывают функцию родительской области видимости, нет возможности передавать аргументы из кода директивы, это потому, что update-fn вызывает updateFn() с фиксированными параметрами, например {msg: "Hello World"}. Небольшое изменение позволяет директиве передавать аргументы, которые, на мой взгляд, гораздо полезнее.

<test color1="color1" update-fn="updateFn"></test>

Обратите внимание, что HTML передает ссылку на функцию, т.е. без () скобок.

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='callUpdate()'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {       
          scope.callUpdate = function() {
            scope.updateFn()("Directive Args");
          }
        }
    }
});

Итак, в приведенном выше примере HTML вызывает локальную область callUpdate функцию, которая затем "извлекает" updateFn из родительской области и вызывает возвращаемую функцию с параметрами, которые может генерировать директива.

http://jsfiddle.net/mygknek2/

Ответ 3

В вашем теге html директивы 'test', имя атрибута функции не должно быть camelCased, но на основе тире.

so - вместо:

<test color1="color1" updateFn="updateFn()"></test>

записи:

<test color1="color1" update-fn="updateFn()"></test>

Это способ angular показать разницу между атрибутами директивы (такими как функция update-fn) и функциями.

Ответ 4

Как пропустить функцию контроллера с двунаправленной привязкой? Тогда вы можете использовать его в директиве точно так же, как в обычном шаблоне (я просто лишил ненужных частей):

<div ng-controller="testCtrl">

   <!-- pass the function with no arguments -->
   <test color1="color1" update-fn="updateFn"></test>
</div>

<script>
   angular.module('dr', [])
   .controller("testCtrl", function($scope) {
      $scope.updateFn = function(msg) {
         alert(msg);
      }
   })
   .directive('test', function() {
      return {
         scope: {
            updateFn: '=' // '=' bidirectional binding
         },
         template: "<button ng-click='updateFn(1337)'>Click</button>"
      }
   });
</script>

Я приземлился на этот вопрос, потому что я попробовал метод выше befire, но почему-то это не сработало. Теперь он отлично работает.

Ответ 5

используйте тире и нижний регистр для имени атрибута (как и другие ответы):

 <test color1="color1" update-fn="updateFn()"></test>

И используйте "=" вместо "&" в области действия:

 scope: { updateFn: '='}

Затем вы можете использовать updateFn, как и любую другую функцию:

 <button ng-click='updateFn()'>Click</button>

Там вы идете!

Ответ 6

Мне пришлось использовать привязку "=" вместо "&" потому что это не работает. Странное поведение.