Angular:使用DOM操作实现ng click-in指令



我是Angular新手,我正在努力解决我认为是标准问题的问题。

我试图实现的是一个名为"clicker"的自定义指令,该指令旨在包含在"ulng-reeat"html元素中。

下面是一个我如何想象我的HTML的例子:

<ul ng-repeat="item in items">
    <clicker>{{item}}</clicker>
    ...
</ul>

为了实现这一点,我创建了一个自定义指令"点击器",如下所示:

myModule.directive('clicker', function() {
return {
    restrict : 'E',
    replace : true,
    transclude: true,
    scope : true,
    template : '<li><a ng-click="showMeClicked()" ng-transclude></a></li>',
    controller: function($scope, $element, $document){
            var test = {}; //In debug $scope, $element, $document are injected here!
           $scope.showMeClicked = function ($scope, $element, $document) {
               //In debug all $scope, $element, $document are undefined here!
               //This line works and deletes all class properties of my <li> along with id properties of their
               //child <a> element. Since $element is undefined this code was the only way I manage to do that action.
               angular.element(document.querySelectorAll('.button_selected')).removeClass('button_selected').children().removeAttr('id');
               //This code does not work since $element is undefined!
               $element.addClass('button_selected');
               $element.children().prop('id', 'button_selected_font');
               //My expected result is:
               //'<li class="button_selected">'
               //     '<a id="button_selected_font" ng-click="showMeClicked()" ng-transclude></a>'
               //'</li>'
           };
         }
};
});

我想做的是让我的"点击器"元素可以点击,点击后我想改变它们在屏幕上的外观。基本上,我需要的是将$元素正确地注入到我的showMeClicked函数中,这样我就可以使用它来设置列表的"class"和锚点的"id"。我试图在示例代码中给出好的注释。

我尝试使用链接功能而不是控制器功能,但当前元素也没有注入其中。我给指令的scope:true属性只是一个例子,如果需要,它可以更改。

我尽量避免使用jQuery,而使用Angular的jqLite。

有人有什么建议吗?

提前感谢!

编辑:目前我没有在我的"ul"上使用ng repeat指令。相反,我手动声明了9个"点击者"标签。因此,在我得到的HTML中,标记被指令中的正确代码所替换,我看到了一个"li"s列表。你可以在这里看到我的"ul"内容:pastebin.com/JPFqcnSU

当我点击任何链接时,它会导致预期的异常:

无法访问未定义的addClass。

您需要通过传递索引来访问当前元素:

$element[0].style...

Javascript

var app = angular.module('myApp',[]);
function MyController(){
    var vm = this;
    this.items = ["a","b","c","d","e"];
}
app.controller('MyController',[MyController])
.directive('clicker',function() {
    return {
        restrict : 'E',
        replace : true,
        transclude: true,
        scope : true,   
        template : '<li><a href="#" ng-click="showMeClicked()" ng-transclude></a></li>',
        link: function(scope,element,doc) {
            scope.showMeClicked = function() {
                 element[0].style.backgroundColor = 'red';
                 angular.element(element[0]).find('a').addClass('magic');
            }
        }
    }
});

HTML

<div ng-app="myApp" ng-controller="MyController as vm">
    <div ng-repeat="item in vm.items">
        <clicker>{{item}}</clicker>
    </div>
</div>

Fiddle

最新更新