angularjs 如何在隔离范围的指令上使用ng-click?

zvokhttg  于 2023-08-02  发布在  Angular
关注(0)|答案(6)|浏览(119)

我可以让ng-click在指令上继承作用域,但在隔离时不行。第一个月
下面是继承作用域的工作示例:https://codepen.io/anon/pen/PGBQvj
下面是一个孤立作用域的坏例子; https://codepen.io/anon/pen/jrpkjp
(单击数字,第一个示例中的数字递增,但第二个示例中的数字不递增)
一些代码...
HTML

<div ng-app="myApp" ng-controller="baseController">
  <my-directive ng-click="hello()" current="current"></my-directive>
</div>

字符串
具有继承作用域的指令:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
        scope.hello = function() {
          scope.current++
        };
      },
      replace: true,
      scope: true,
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });


相同的指令,但具有独立的作用域:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
        scope.hello = function() {
          scope.current++
        };
      },
      replace: true,
      scope: {
        current:'='
      },
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });

bttbmeg0

bttbmeg01#

问题是你试图调用一个未定义的函数。如果您希望在隔离指令中定义逻辑,则不需要传入函数引用。

<my-directive current="current"></my-directive>

字符串
这里不能传递ng-click="hello()"。这是控制器的作用域,因此hello()未定义。
而是将ng-click事件移动到指令的模板中

template: '<div ng-click="hello()">


还有一点:您正在使用指令的link()函数。这是为DOM操作保留的。相反,在controller函数中定义hello()

controller: function ($scope) {
  $scope.hello = function() {
      $scope.current++
  }
},


不过,我认为这里还有一个更大的架构问题。一个独立的指令或组件的意义在于封装内部的逻辑。它不应该操纵外部状态。在本例中,您正在递增一个数字。如果在应用程序的另一部分中,您希望递减一个数字,该怎么办?复制带有递减逻辑的指令会产生大量的代码重复。
相反,您应该在控制器中定义递增或递减功能,并将其传递给指令。

<my-directive change-number="increment()" current="current"></my-directive>


然后,使用&语法将函数引用绑定到指令:

scope: {
  current:'=',
  changeNumber: '&'
},


然后从模板调用changeNumber。这样做非常有利于代码重用。

pokxtpni

pokxtpni2#

将hello函数添加到控制器中。让它更新current的值并将其传递到指令的隔离作用域中

.controller('baseController', function($scope) {
    $scope.current = 1;
    $scope.hello = function() {         
      $scope.current++;

    };

字符串
})
CodePen

nhhxz33t

nhhxz33t3#

你需要将对象从控制器传递到指令
将js更改为

angular.module('myApp', [])
.controller('baseController', function($scope) {
$scope.current = {};
$scope.current.val=1;
})
.directive('myDirective', function() {
return {
  link: function(scope, element, attrs) {      scope.internalcurrent= scope.current || {};
                                         //scope.internalcurrent.val=1;
    scope.internalcurrent.hello = function() {
      scope.internalcurrent.val++

    };
  },
  replace: true,
  scope: {
    current:'='
  },
  template: '<div><child>      <strong>{{ internalcurrent.val }}</strong></child></div>'
}
})
.directive('child', function() {
return {
  link: function(scope, element, attrs) {
    console.log("horeee");
  }
}
});

字符串
和你的html

<div ng-app="myApp" ng-controller="baseController">
<my-directive ng-click="hello()" current="current"></my-directive>
</div>

2admgd59

2admgd594#

如果你想在指令中定义click函数,那么你需要像这样在模板中附加处理程序:

template: '<div ng-click="hello()"><child><strong>{{current}}</strong></child></div>'

字符串
当你把处理程序附加到指令声明中时,就像你的坏例子一样,你基本上是在告诉ng-click你想调用当前作用域(控制器的作用域)上的函数。这可能看起来不像是正在发生的事情,因为在您的工作示例中,您的函数是从myDirective中定义的,但它实际上被附加到作用域,在本例中(工作示例)是控制器的作用域。
CodePen

bbuxkriu

bbuxkriu5#

如果您无法将“ng-click”移动到指令模板中,另一个解决方案是您可以将函数放在父作用域中。就像这样:
替换:

link: function(scope, element, attrs) {      
    scope.hello = function() {
      scope.current++
    };
  }

字符串
用于:

link: function(scope, element, attrs) {      
    scope.$parent.hello = function() {
      scope.current++
    };
  }


这将使函数“hello”在控制器的作用域中可用。

dhxwm5r4

dhxwm5r46#

使用isolated指令,您可以使用ng-click="$parent.hello()"而不是ng-click="hello()"。很高兴在你的问题上发帖。
说明:当你在一个元素上使用ng-click时,它的值(hello())将相对于它的外部作用域来计算,即示例中的控制器作用域。当创建使用非隔离作用域的指令时,controller的作用域被传递给link函数,hello定义在controller的作用域上。
//编辑代码:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
    $scope.hello = () => $scope.current ++;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
      },
      replace: true,
      scope: {
        current:'='
      },
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });

字符串

相关问题