Angularjs 使用click事件注入DOM元素的角度指令 内容编辑

Angularjs 使用click事件注入DOM元素的角度指令 内容编辑,angularjs,directive,insertafter,Angularjs,Directive,Insertafter,目标是创建一个可以附加到文本框的指令,当文本框具有焦点时,文本框后面会出现一个图像/按钮,图像/按钮单击事件将触发指令中包含的函数。目标是使该功能在指令中完全独立,以便可以轻松地在许多页面或应用程序中部署 图像/按钮出现在文本框后,没有问题,但按钮的单击事件不会触发该功能。我已经用示例代码创建了一个 在plunk中,第15行定义了一个名为“搜索”的函数,它只不过发出警报。当文本框具有焦点时,按钮按预期显示,第34行成功调用搜索函数,这意味着函数本身正在工作。但是,按钮的单击事件不会触发搜索功能

目标是创建一个可以附加到文本框的指令,当文本框具有焦点时,文本框后面会出现一个图像/按钮,图像/按钮单击事件将触发指令中包含的函数。目标是使该功能在指令中完全独立,以便可以轻松地在许多页面或应用程序中部署

图像/按钮出现在文本框后,没有问题,但按钮的单击事件不会触发该功能。我已经用示例代码创建了一个

在plunk中,第15行定义了一个名为“搜索”的函数,它只不过发出警报。当文本框具有焦点时,按钮按预期显示,第34行成功调用搜索函数,这意味着函数本身正在工作。但是,按钮的单击事件不会触发搜索功能


原职 我正在尝试在我们的应用程序中重新创建一些功能,这些功能目前正通过jQuery实现。该功能涉及将一个伪类附加到一个文本框,然后jQuery将该文本框拾取,并在文本框之后立即将一个放大镜图像注入DOM。单击图像会弹出一个对话框

到目前为止,我已经完成了一个简单的html页面、一个简单的控制器和一个简单的指令。当文本框具有焦点时,图像将按预期显示。但是,ng click指令不会触发

以下是html:

这是指令:

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);
            }

        });
    }

};

};
angular
.module('应用程序')
.指令('userSearch',userSearch);
函数userSearch($compile){
返回{
限制:“EAC”,
要求:'ngModel',
//是的,
范围:{
//搜索:函数(callerid){
//警报(callerid);
//}
},
模板:“用户的别名为:。”,
//控制器:UserSearchController,
链接:函数(范围、元素、属性){
元素绑定('focus',函数(){
//警报(attrs.id+“| |”+attrs.userSearch);
var nextElement=element.parent().find('.openuserdialog').length;
如果(nextElement==0){
var放大镜=$compile(“”)(范围);
元素后(放大镜);
}
});
}
};
};
目前,我很乐意通过在控制器中点击pc.search或在隔离范围内搜索来获得火灾警报。到目前为止,两者都不起作用。我肯定这是一些简单的东西,但我不知道是什么


解决方案 感谢谷歌论坛上的一位用户向我展示了指令的controllerAs属性。此版本现在可以完美工作:

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'

};

};
angular
.module('应用程序')
.指令('userSearch',userSearch);
函数userSearch($compile){
返回{
控制器:函数()
{
this.search=函数(){
警报(“测试”);
};
},
链接:函数(范围、元素、属性){
元素绑定('focus',函数(){
var nextElement=element.parent().find('.openuserdialog').length;
if(nextElement==0){
var btn=“”;
元素($compile(btn)(scope));
}
});
},
controllerAs:“用户搜索”
};
};

您在指令中使用的是隔离作用域,这意味着它无权访问其父作用域。所以在这种情况下,您需要将方法引用显式地传递给指令。通过指令隔离范围内的新变量向指令范围传递方法引用

标记

<input id="txtAlias" 
   type="text" ng-model="pc.results" 
   user-search search="search(id)" />

scope: {
   search: '&'
}
还将编译模板更改为

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);
 }
if(nextElement==0){
var放大镜=$compile(“”)(范围);
元素后(放大镜);
}
相反,我希望编译后的模板仅作为指令函数的
template
的一部分。我将根据
ng if=“expression”
指令显示和隐藏它


与其尝试注入DOM,然后尝试连接到刚才注入的东西,不如将输入和搜索按钮/图标都包装在一个指令中。您可以使用隔离作用域和双向绑定来连接输入和按钮:

HTML:


你好{{name}}

这里有一个控制器和一个指令来演示这一点。注意隔离作用域中的“=”,当指令在模板中使用时,创建到相应属性的双向绑定

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>'
  }
})
app.controller('MainCtrl',函数($scope){
$scope.name='World';
$scope.search=function(){alert('search clicked');}
});
app.directive('searchBox',function(){
返回{
限制:'E',
范围:{
searchFunction:“=”,
数据:'=',
},
模板:“搜索”
}
})
您应该能够轻松地将
按钮
元素替换为
img
或您内心所希望的任何其他元素

这是一个plunk,其中搜索框有一个alert(),在指令的文本框中键入会影响控制器作用域的相应属性:

谢谢你,潘卡吉。我按照您的建议更改了scope属性,并更改了图像的ng click值。没有变化。图像会出现,但单击时不会发生任何变化。最终,点击图像应该触发一个单独的功能。目前,如果该函数只是一个警报,就可以了。有什么建议吗?@johnesley那是我的错。。查看更新的回答好的,范围和ng click属性按照您的建议进行了修改。没有变化。单击图像时仍然没有功能或警报触发。呈现的html在图像控件中显示以下内容:好的,范围和ng click属性已按照您的建议进行了修改。没有变化。单击图像时仍然没有功能或警报触发。呈现的html显示以下内容
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);
 }
  <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>'
  }
})