目标是创建一个可以附加到文本框的指令,当文本框具有焦点时,文本框后面会出现一个图像/按钮,图像/按钮单击事件将触发指令中包含的函数。目标是使该功能在指令中完全自包含,因此可以在许多页面或应用程序中轻松部署。
图像/按钮出现在文本框之后没有问题,但按钮的单击事件不会触发该功能。我用示例代码创建了一个plunkr。
在插件中,第15行定义了一个名为' search,'除了发出警报外什么都没做。当文本框具有焦点时,按钮按预期显示,第34行成功调用搜索功能,这意味着该功能本身正在工作。但是,按钮的点击事件不会触发搜索功能。
我试图在我们的应用程序中重新创建一些当前使用jQuery完成的功能。该功能涉及将伪类附加到文本框,然后由jQuery拾取,并在文本框之后立即将放大镜的图像注入DOM。单击图像会弹出一个对话框。
到目前为止,我所完成的是一个简单的html页面,一个简单的控制器和一个简单的指令。当文本框具有焦点时,图像将按预期显示。但是,ng-click指令不会触发。
这里是html:
<input
id="txtAlias"
type="text"
ng-model="pc.results"
user-search />
</div>
这是控制器:
angular
.module('app')
.controller('PeopleController', PeopleController);
PeopleController.$inject = ['$http'];
function PeopleController() {
var pc = this;
pc.results = '';
pc.search = function () {
alert('test');
};
}
这是指令:
angular
.module('app')
.directive('userSearch', userSearch);
function userSearch($compile) {
return {
restrict: 'EAC',
require: 'ngModel',
//transclude: true,
scope: {
//search : function(callerid){
// alert(callerid);
//}
},
template: "The user's alias is: <b><span ng-bind='pc.results'></span>.",
//controller: UserSearchController,
link: function (scope, element, attrs) {
element.bind('focus', function () {
//alert(attrs.id + ' || ' + attrs.userSearch);
var nextElement = element.parent().find('.openuserdialog').length;
if (nextElement == 0) {
var magnifyingglass = $compile('<img src="' + homePath + 'Images/zoomHS.png" ' +
'alt="User Search" ' +
'ng-click="pc.search("' + attrs.id + '")" ' +
'class="openuserdialog">')(scope);
element.after(magnifyingglass);
}
});
}
};
};
目前,我很乐意通过在控制器中点击pc.search或在隔离范围内搜索来获取警报。到目前为止,两者都没有奏效。我确定它缺少一些简单的东西,但我无法弄清楚是什么。
感谢Google论坛上的用户向我展示了指令的控制器属性。这个版本现在完美无缺:
angular
.module('app')
.directive('userSearch', userSearch);
function userSearch($compile){
return {
controller: function ()
{
this.search = function () {
alert('Test');
};
},
link: function (scope, element, attrs) {
element.bind('focus', function () {
var nextElement = element.parent().find('.openuserdialog').length;
if (nextElement === 0) {
var btn = '<img src="' + homePath + 'Images/zoomHS.png" ' +
'ng-click="userSearch.search()" ' +
'class="openuserdialog" />';
element.after($compile(btn)(scope));
}
});
},
controllerAs: 'userSearch'
};
};
答案 0 :(得分:0)
您在指令中使用隔离范围,这意味着它无权访问其父范围。因此,在这种情况下,您需要将方法引用显式传递给指令。在隔离的指令范围内通过新变量传递对指令范围的方法引用。
<强>标记强>
<input id="txtAlias"
type="text" ng-model="pc.results"
user-search search="search(id)" />
scope: {
search: '&'
}
由于您无权访问父作用域,因此您不能像使用pc.
那样使用控制器别名。只需使用以下没有别名。因此,指令将直接绑定指令范围内的那些变量。
template: "The user's alias is: <b><span ng-bind='results'></span>.",
同时将编译模板更改为
if (nextElement == 0) {
var magnifyingglass = $compile('<img src="' + homePath + 'Images/zoomHS.png" ' +
'alt="User Search" ' +
'ng-click="search({id: ' + attrs.id + '})' +
'class="openuserdialog">')(scope);
element.after(magnifyingglass);
}
相反,我希望将编译的模板仅作为指令函数template
的一部分。我将根据ng-if="expression"
指令显示和隐藏它。
答案 1 :(得分:0)
而不是尝试注入DOM,然后尝试连接到刚注入的那个东西,而不是在指令中包含输入和搜索按钮/图标。您可以使用隔离范围和双向绑定来连接输入和按钮:
HTML:
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<search-box data="name" search-function="search"></search-box>
</body>
这是一个控制器和一个证明这一点的指令。请注意隔离范围中的“=”,在模板中使用该指令时,创建与相应属性的双向绑定。
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.search= function() { alert('search clicked'); }
});
app.directive('searchBox', function() {
return {
restrict: 'E',
scope: {
searchFunction: '=',
data: '=',
},
template: '<input ng-model="data" /><button ng-click="searchFunction()">Search</button>'
}
})
您应该可以使用button
或其他任何您想要的内容轻松替换img
元素。
这是一个带有alert()的插件,在指令的文本框中输入会影响控制器范围的相应属性: http://plnkr.co/edit/0lj4AmjOgwNZ2DJMSHDj