AngularJS模板中的动态id

AngularJS模板中的动态id,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我将jQuery插件包装在AngularJS指令中。我想调用指令的方式是,例如: <my-dialog data-trigger-id="myTriggerId">My dialog content...</my-dialog> 我的对话框内容。。。 在我的指令模板中,它如下所示: <button id="{{triggerId}}">Button text...</button> <button id="myTriggerId">

我将jQuery插件包装在AngularJS指令中。我想调用指令的方式是,例如:

<my-dialog data-trigger-id="myTriggerId">My dialog content...</my-dialog>
我的对话框内容。。。
在我的指令模板中,它如下所示:

<button id="{{triggerId}}">Button text...</button>
<button id="myTriggerId">Button text...</button>
按钮文本。。。
我将jQuery插件的事件(您可以在其中指定触发器选择器)附加到我的指令的link函数中。我的问题是,如果我在指令模板中硬编码按钮的id,它就会工作,如下所示:

<button id="{{triggerId}}">Button text...</button>
<button id="myTriggerId">Button text...</button>
按钮文本。。。
生成的html在浏览器中看起来很好,这意味着使用动态id呈现元素是可行的。只是如果我使用动态id,jQuery插件找不到这个元素,但是它可以与硬编码版本一起工作。 我还查看了AngularJS compile,因为jQuery插件想要初始化元素的地方似乎还不存在

有没有我找不到的人?谢谢

编辑:我最终设法简化它并创建了一个JSFIDLE示例。如果您运行该示例,您将在控制台中看到我记录该元素时该元素不存在,但是如果您检查DOM,您将看到它在那里并且具有正确的id。 但是,如果在模板中硬编码id(id=test而不是id={{elemId}}),控制台日志将显示可以找到一个元素。我希望这有助于找到解决办法


当您调用$(“#test”).length时,该摘要尚未在DOM中呈现

您需要添加$timeout,以便完成摘要,然后调用您的方法

var app = angular.module('app', []);
app.directive('myDialog', ['$timeout', function ($timeout) {
    return {
        restrict: 'E',
        template: '<button id="{{elemId}}" class="{{elemClass}}">Open dialog</button>',
        link: function (scope, element, attrs) {

            var selector = scope.elemSelector,
            elemClass = (selector.indexOf('.') > -1) ? selector.substr(1) : '',
            elemId = (selector.indexOf('#') > -1) ? selector.substr(1) : '';

            scope.elemClass = elemClass;
            scope.elemId = elemId;

            $timeout(function() {
                console.log('elem: ', $('#test').length);
            });
            // jQuery plugin init here but element doesn't seem to exist yet.

        },
        scope: {
            elemSelector: '@'
        }
    }
}]);
var-app=angular.module('app',[]);
app.directive('myDialog',['$timeout',function($timeout){
返回{
限制:'E',
模板:“打开对话框”,
链接:函数(范围、元素、属性){
变量选择器=scope.elemSelector,
elemClass=(selector.indexOf('.')>-1)?selector.substr(1):“”,
elemId=(selector.indexOf('#')>-1)?selector.substr(1):“”;
scope.elemClass=elemClass;
scope.elemId=elemId;
$timeout(函数(){
log('elem:',$('#test').length);
});
//jQuery插件在这里初始化,但元素似乎还不存在。
},
范围:{
elemSelector:“@”
}
}
}]);

尽管需要注意的是,您应该尝试减少任何Id,而只使用$(element),除非您的jQuery绝对需要Id。

您可以创建JSFIDLE或为您的指令提供代码,以便我们了解您在做什么。谢谢您的评论。遗憾的是,它不是开源的,但我将尝试创建一个类似的示例。您希望使用唯一id而不是$(element).length有什么具体原因吗?非常感谢您的回答和解决方案。我不仅仅是让我的代码工作,而是试图理解AngularJS的引擎盖下发生了什么。我需要id而不是元素的原因是插件是一个需要触发器元素的覆盖。我把这个触发器元素放在指令模板中。为了能够在一个页面中使用多个这些指令,我将提供唯一的ID。然而,在与同事讨论这个问题时,我也意识到,将jQuery插件封装在指令中并不是一种真正的角度。我想Angular指令应该是KISS。将jQuery插件包装在Angular指令中是绝对可以接受的。。。除非有一个角度相当于插件,这似乎是稀疏的。但是,我可能建议在指令中创建一个唯一的ID,而不是让用户传入。您可以执行id='myDirective\$id'之类的操作,然后在jQuery调用中,只需执行$(“#mydirectve\'+$scope.$id)。谢谢,这是一个好主意,这将使项目中的其他开发人员更容易使用该指令。显然,我可以也将尝试这个方法,但是如果没有$timeout方法,这个方法会起作用吗?我在模板中使用id=“myDirective”{{{$id}}进行了测试,虽然效果很好,但仍然需要$timeout.:)是的,仍然需要$timeout。很高兴它成功了!