1

別の (しかし関連する) DOM 要素をクエリしようとしている、かなり単純なディレクティブがあります。

関連するマークアップ:

<a href="#target-id" data-collapsible="isCollapsed">Open</a>
...
<div id="target-id">...</div>

コントローラ:

app.controller('MyController', ['$scope', function( $scope ) {
    $scope.isCollapsed = true;
}]);

指令:

app.directive('collapsible', function() {
    return {
        restrict: 'A',
        link: function( scope, el, attrs ) {
            var target = attrs.href.slice(1); // "target-id"
            console.log(document.getElementById(target)); // this will be null
        }
    };
});

問題は、DOM クエリ ( document.getElementById(target)) が使用可能になる前に実行されて<div id="target-id">...</div>いることです。これまでのところ、競合状態を回避するには、クエリを$timeout100 ~ 500 ミリ秒の遅延でラップすることしかできませんでしたが、これは間違っているように感じます。

確かに私は何か間違ったことをしている、および/またはこれについてもっと良い方法があるはずですか?

This SO threadは同様の問題の概要を説明していますが、ゼロ遅延タイムアウトは機能しません。

4

2 に答える 2

2

したがって、コメントで述べたように、それを行う簡単な方法は、 ng-click / ng-show を使用して表示を切り替えることです

<a href="#target-id" ng-click='visibleTargetId=!visibleTargetId'>Open</a>
<div id="target-id" ng-show='visibleTargetId'>

もちろん、関数を使用して行うこともできますが、これには変数を手動で設定する必要があり、実際にはスケーラブルではありません

変数を完全に削除してディレクティブを引き続き使用する場合は、そのディレクティブでクリック イベントをバインドすることもできます。ここでフィドルを見ることができます:http://jsfiddle.net/DotDotDot/vGCJF/3/

jQueryのロードを避けたい場合はバニラJSを使用しましたが、たとえばjQueryのtoggle()関数でも使用できます

ディレクティブのリンク関数で、コードは非常に単純です。

 el.bind('click', function(e){
 //whatever you want to do

}

幸運を

于 2013-07-30T13:56:30.987 に答える