单击时从自定义指令调用函数? - AngularJS

Calling a function from custom directive on click? - AngularJS

我在单击按钮时从我的自定义指令调用一个函数。

这是我在 JSP

中的代码
<input type="button" value="button" text="{{item.id}}" data-href="divSlide" show-notifications>

这是我的自定义指令

    hello.directive("showNotifications", ["$interval", function($interval, $scope) {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {            
            //On click
            $(elem).click(function() {
                console.log('before');              
                scope.$parent.getJSON(scope.text);
               if ($('tr#' + $(this).data("href")).is(":visible")) {
                    $('tr#' + $(this).data("href")).remove();
                } else {

                    console.log('after');
                    $(this).closest('tr').after('<tr id="' + $(this).data("href") + '"><td colspan="5">' + $('#' + $(this).data("href")).html() + '</td></tr>');                    
                }    
            });
        },
        scope:{
            text: "@text"
        }
    };
}]);

这是我的职能

$scope.getJSON= function(id){
        jsonService.getJSONData(id).then(function(data){
            $scope.data= [];                
                $scope.data= data['dataList'];
                console.log('insidejson');              
            }
           });
    };

当我执行代码时,控制台按以下顺序打印日志,

before
after
insidejson

但理想情况下应该是

before 
insidejson
after

为什么在函数执行之前执行函数调用之后的下一条语句?

我做错了什么?

您必须 return 承诺并使用它:

$scope.getJSON= function(id){
  return jsonService.getJSONData(id).then(function(data){

$(elem).click(function() {
  var $element = $(this);
  console.log('before');
  scope.$parent.getJSON(, scope.text).then(function() {
           if ($('tr#' + $element.data("href")).is(":visible")) {

请注意,this 将不再指向函数内的元素。所以我将它分配给一个变量并且已经将它包装到一个 jQuery 元素中。我还建议您将函数传递给指令:

<input type="button" show-notifications call="getJson">

在你的指令中:

scope:{
        text: "@text",
        call: "="
    },
link: function(scope, elem, attrs) {            
        //On click
        $(elem).click(function() {
            console.log('before');              
            scope.call(scope.text).then(...

jsonService.getJSONData 是异步调用,所以代码在这一行之后继续:scope.$parent.getJSON(, scope.text); 不等待 $scope.getJSON 回答。

要解决,可以使用$q服务。
只需添加 $q 服务并使用 $scope.getJSON 函数,如下所示:

$scope.getJSON= function(id){
         var deferred = $q.defer();
        jsonService.getJSONData(id).then(function(data){
               console.log('insidejson'); 
                deferred.resolve(data);           
            }
           });
        return deferred.promise;
    };

并且:

  $(elem).click(function() {
         console.log('before');              
         scope.$parent.getJSON(scope.text).then(function(data){
               if ($('tr#' + $(this).data("href")).is(":visible")) {
                        $('tr#' + $(this).data("href")).remove();
                    } else {
                        console.log('after');
                        $(this).closest('tr').after('<tr id="' + $(this).data("href") + '"><td colspan="5">' + $('#' + $(this).data("href")).html() + '</td></tr>');                    
                    }    
                       });

                });

现在所有嵌套在 then 中的代码都将在函数 getJSON 解析数据后执行 deferred.resolve(data);

函数

   jsonService.getJSONData(id).then(function(data){
        $scope.data= [];                
            $scope.data= data['dataList'];
            console.log('insidejson');              
        }
       });

是一个异步函数。因此它会在最后执行