カスタムディレクティブを使用するというPavelのアドバイスに従い、次のバージョンは、routeConfigにペイロードを追加する必要がないバージョンで、超宣言的であり、slice()
注意を向けているパスを変更するだけで、パスの任意のレベルに対応するように調整できます。 。
app.directive('detectActiveTab', function ($location) {
return {
link: function postLink(scope, element, attrs) {
scope.$on("$routeChangeSuccess", function (event, current, previous) {
/*
Designed for full re-usability at any path, any level, by using
data from attrs. Declare like this:
<li class="nav_tab">
<a href="#/home" detect-active-tab="1">HOME</a>
</li>
*/
// This var grabs the tab-level off the attribute, or defaults to 1
var pathLevel = attrs.detectActiveTab || 1,
// This var finds what the path is at the level specified
pathToCheck = $location.path().split('/')[pathLevel] ||
"current $location.path doesn't reach this level",
// This var finds grabs the same level of the href attribute
tabLink = attrs.href.split('/')[pathLevel] ||
"href doesn't include this level";
// Above, we use the logical 'or' operator to provide a default value
// in cases where 'undefined' would otherwise be returned.
// This prevents cases where undefined===undefined,
// possibly causing multiple tabs to be 'active'.
// now compare the two:
if (pathToCheck === tabLink) {
element.addClass("active");
}
else {
element.removeClass("active");
}
});
}
};
});
パス上にを$routeChangeSuccess
配置するの$watch
ではなく、イベントをリッスンすることで目標を達成しています。私は、時計が各$digest
サイクルで作動するように思うので、これはロジックがより頻繁に実行されるべきではないという信念の下で働きます。
ディレクティブ宣言でパスレベルの引数を渡して、呼び出します。これは、href
属性と照合する現在の$ location.path()のチャンクを指定します。
<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>
したがって、タブがパスの基本レベルに反応する必要がある場合は、引数を「1」にします。したがって、location.path()が "/ home"の場合、の "#/ home"と一致しhref
ます。パスの2番目のレベル、3番目、または11番目のレベルに反応するタブがある場合は、それに応じて調整します。この1以上のスライスは、インデックス0に存在するhref内の悪質な「#」をバイパスします。
<a>
要素がhref
属性の存在を想定しているため、で呼び出すことが唯一の要件であり、現在のパスと比較します。ただし、またはで呼び出すことを好む場合は、親要素または子要素の読み取り/書き込みにかなり簡単に適応できます<li>
。これは、pathLevel引数を変更するだけで多くのコンテキストで再利用できるためです。読み取る深さがロジックで想定されている場合、ナビゲーションの複数の部分で使用するディレクティブの複数のバージョンが必要になります。
編集3/18/14:ソリューションは一般化が不十分undefined
であり$location.path()
、と要素のの両方に対して返される 'activeTab'の値の引数を定義した場合にアクティブになりますhref
。理由:undefined === undefined
。その状態を修正するために更新されました。
その作業中に、次のようなテンプレート構造を使用して、親要素で宣言できるバージョンがあったはずであることに気付きました。
<nav id="header_tabs" find-active-tab="1">
<a href="#/home" class="nav_tab">HOME</a>
<a href="#/finance" class="nav_tab">Finance</a>
<a href="#/hr" class="nav_tab">Human Resources</a>
<a href="#/quarterly" class="nav_tab">Quarterly</a>
</nav>
このバージョンはリモートでBootstrapスタイルのHTMLに似ていないことに注意してください。しかし、それはより近代的で、使用する要素が少ないので、私はそれに不慣れです。このバージョンのディレクティブと元のディレクティブは、依存関係として宣言できるドロップインモジュールとしてGithubで利用できるようになりました。誰かが実際にそれらを使用する場合、私はそれらをBower化できれば幸いです。
また、を含むブートストラップ互換バージョンが<li>
必要な場合は、この元の投稿の後に出てきたと思われる angular-ui-bootstrap Tabsモジュールを使用できます。これはおそらくこれよりもさらに宣言的です。基本的なものについてはそれほど簡潔ではありませんが、無効化されたタブや、アクティブ化および非アクティブ化時に起動する宣言型イベントなど、いくつかの追加オプションを提供します。