如何将 ng-click 绑定到自定义指令并调用父函数?
How to bind ng-click to a custom directive and call a parent function?
我们正在使用 Angular 1.4.2,我正在尝试使用 ng-click 从指令中获取计数值,将其传递给函数,然后将其传递给父控制器。经过一些努力,它在 plunker 中工作,但不幸的是,当我试图将此功能移回主代码时,我无法让控制器绑定到隔离范围。
应该很简单,但我已经尝试将当前控制器注入指令并尝试创建一个新控制器,但是当我按下按钮时没有任何反应。
代码如下:
模板:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@1.4.2" data-semver="1.4.2" src="https://code.angularjs.org/1.4.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div id="app" ng-app="app">
<div ng-controller="mainCtrl">
<my-directive ctrl-fn="ctrlFn(count = count + 10)"></my-directive>
</div>
</div>
</body>
</html>
脚本:
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope){
$scope.count = 0;
$scope.ctrlFn = function() {
console.log('In mainCtrl ctrlFn!');
//$scope.count += 10; Old hardcoded value.
console.log("count is: " + JSON.stringify($scope.count));
//Call service here
};
});
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
template: "<div><button ng-click='ctrlFn()'>Click Here</button></div>",
link: function(scope, element, attributes) {
scope.ctrlFn(count);
}
};
});
这是我试图在主代码库中修改的模板代码:
<div>
<div layout="row">
<results-loader ctrl-fn="ctrlFn(count = count + 10)"></results-loader>
<md-button class="md-raised md-primary md-button" ng-click="ctrlFn()" flex>Click Me</md-button>
</div>
</div>
这里是我在指令中使用现有控制器作为父控制器的地方。它是在路由中定义的,而不是在 ng-controller 中定义的,并且已经用于此视图。
myresultsCtrl.$inject = ['$scope', ' myService'];
/* @ngInject */
function myresultsCtrl($scope, myService) {
$scope.count = 0;
etc...
然而,它显然没有正确绑定,因为我从来没有使用 ng-click 点击指令或这个函数。
就像我说的,我尝试向模板添加一个新的控制器,然后我尝试将一个现有的控制器注入指令,但都没有成功。我从指令中取出模板并尝试使用 ctrl-fn 将 ng-click 直接放入模板中,但我不确定如何将点击与调用指令的 ctrl-fn 属性连接起来都在模板中?这里的想法是将模板移动到它自己的 html 文件中,并从指令中引用它,如:模板:“myFile.html。我正在尝试尽可能多地封装以使其成为一个可重用的组件。
我没有使用自定义指令。
这里直接link到plunker.
我不知道您的确切任务,但请重新考虑您的架构。为什么要计算指令中的值?在您的简单情况下,最好计算服务或控制器中的值,而不是指令。
在指令中注入控制器是anti-angular模式。你需要重新考虑你的意图。最好将数字传递给指令,在那里进行计算并将数字发送回控制器。由于 two-way 数据绑定,它无需额外代码即可工作。这是你的 plunker 的一个分支:
http://plnkr.co/edit/KpB6bv5tHvXSvhErLcEp?p=preview
主要部分是指令的定义:
<div><span>{{count}}</span><br /><button ng-click='myFunction()'>Calculate</button></div>
我不想回答我自己的问题,因为这可能会有负面影响,但在这种情况下,我不知道我是否可以很好地解释问题以获得正确答案。让我失望的是将我的工作 plunker 代码集成到我们现有的代码库中。
我被卡住的地方是如何为这个用例正确设置控制器。虽然我在模块中声明了我的控制器并注入了控制器,因为它已经绑定到该视图,但我需要在指令本身中定义控制器。一旦我同时完成所有这三个操作,一切就开始正常工作了。
以下是一些代码片段:
angular.module('directiveName', [])
.directive('directiveName', directiveName)
.controller('injectedCtrl', injectedCtrl)
etc...
var directive = {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
template: "<div><button ng-click='ctrlFn()'>Click Here</button></div>",
controller: "injectedCtrl",
link: function(scope, element, attributes) {
scope.ctrlFn(); //This will pass to the parent controller: injectedCtrl, where $scope resides.
}
}
return directive;
}
injectedCtrl.$inject = ['$scope', 'myService'];
/* @ngInject */
function injectedCtrl($scope, myService) {
$scope.ctrlFn = function() {
//do something
}
etc...
HTML 代码:
当从指令中单击按钮时,这里的 ctrlFn 是在 DDO 中我的指令隔离范围内的引用。这采用传入的外部函数,即:ctrlFn(),然后可以从指令中调用它来调用父控制器。
<div layout="row">
<results-loader ctrlFn="ctrlFn()"></results-loader>
</div>
我 post 这样做是为了帮助可能有此用例的其他人,因为弄清楚这一点并不容易。
Dah Wahlins post 更详细地探讨了这个主题:Creating Custom AngularJS Directives Part 3 - Isolate Scope and Function Parameters 以及是什么帮助理清了我的思路。
我们正在使用 Angular 1.4.2,我正在尝试使用 ng-click 从指令中获取计数值,将其传递给函数,然后将其传递给父控制器。经过一些努力,它在 plunker 中工作,但不幸的是,当我试图将此功能移回主代码时,我无法让控制器绑定到隔离范围。
应该很简单,但我已经尝试将当前控制器注入指令并尝试创建一个新控制器,但是当我按下按钮时没有任何反应。
代码如下:
模板:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@1.4.2" data-semver="1.4.2" src="https://code.angularjs.org/1.4.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div id="app" ng-app="app">
<div ng-controller="mainCtrl">
<my-directive ctrl-fn="ctrlFn(count = count + 10)"></my-directive>
</div>
</div>
</body>
</html>
脚本:
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope){
$scope.count = 0;
$scope.ctrlFn = function() {
console.log('In mainCtrl ctrlFn!');
//$scope.count += 10; Old hardcoded value.
console.log("count is: " + JSON.stringify($scope.count));
//Call service here
};
});
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
template: "<div><button ng-click='ctrlFn()'>Click Here</button></div>",
link: function(scope, element, attributes) {
scope.ctrlFn(count);
}
};
});
这是我试图在主代码库中修改的模板代码:
<div>
<div layout="row">
<results-loader ctrl-fn="ctrlFn(count = count + 10)"></results-loader>
<md-button class="md-raised md-primary md-button" ng-click="ctrlFn()" flex>Click Me</md-button>
</div>
</div>
这里是我在指令中使用现有控制器作为父控制器的地方。它是在路由中定义的,而不是在 ng-controller 中定义的,并且已经用于此视图。
myresultsCtrl.$inject = ['$scope', ' myService'];
/* @ngInject */
function myresultsCtrl($scope, myService) {
$scope.count = 0;
etc...
然而,它显然没有正确绑定,因为我从来没有使用 ng-click 点击指令或这个函数。
就像我说的,我尝试向模板添加一个新的控制器,然后我尝试将一个现有的控制器注入指令,但都没有成功。我从指令中取出模板并尝试使用 ctrl-fn 将 ng-click 直接放入模板中,但我不确定如何将点击与调用指令的 ctrl-fn 属性连接起来都在模板中?这里的想法是将模板移动到它自己的 html 文件中,并从指令中引用它,如:模板:“myFile.html。我正在尝试尽可能多地封装以使其成为一个可重用的组件。
我没有使用自定义指令。
这里直接link到plunker.
我不知道您的确切任务,但请重新考虑您的架构。为什么要计算指令中的值?在您的简单情况下,最好计算服务或控制器中的值,而不是指令。
在指令中注入控制器是anti-angular模式。你需要重新考虑你的意图。最好将数字传递给指令,在那里进行计算并将数字发送回控制器。由于 two-way 数据绑定,它无需额外代码即可工作。这是你的 plunker 的一个分支:
http://plnkr.co/edit/KpB6bv5tHvXSvhErLcEp?p=preview
主要部分是指令的定义:
<div><span>{{count}}</span><br /><button ng-click='myFunction()'>Calculate</button></div>
我不想回答我自己的问题,因为这可能会有负面影响,但在这种情况下,我不知道我是否可以很好地解释问题以获得正确答案。让我失望的是将我的工作 plunker 代码集成到我们现有的代码库中。
我被卡住的地方是如何为这个用例正确设置控制器。虽然我在模块中声明了我的控制器并注入了控制器,因为它已经绑定到该视图,但我需要在指令本身中定义控制器。一旦我同时完成所有这三个操作,一切就开始正常工作了。
以下是一些代码片段:
angular.module('directiveName', [])
.directive('directiveName', directiveName)
.controller('injectedCtrl', injectedCtrl)
etc...
var directive = {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
template: "<div><button ng-click='ctrlFn()'>Click Here</button></div>",
controller: "injectedCtrl",
link: function(scope, element, attributes) {
scope.ctrlFn(); //This will pass to the parent controller: injectedCtrl, where $scope resides.
}
}
return directive;
}
injectedCtrl.$inject = ['$scope', 'myService'];
/* @ngInject */
function injectedCtrl($scope, myService) {
$scope.ctrlFn = function() {
//do something
}
etc...
HTML 代码:
当从指令中单击按钮时,这里的 ctrlFn 是在 DDO 中我的指令隔离范围内的引用。这采用传入的外部函数,即:ctrlFn(),然后可以从指令中调用它来调用父控制器。
<div layout="row">
<results-loader ctrlFn="ctrlFn()"></results-loader>
</div>
我 post 这样做是为了帮助可能有此用例的其他人,因为弄清楚这一点并不容易。
Dah Wahlins post 更详细地探讨了这个主题:Creating Custom AngularJS Directives Part 3 - Isolate Scope and Function Parameters 以及是什么帮助理清了我的思路。