1

http://jsfiddle.net/MTzJF/36/

上記のJSFiddleは、問題を説明するために設定されています。しかし、基本的に:

HTML:

<breadcrumb></breadcrumb>
<div ng-view></div>

Angularディレクティブとルーティング:

angular
    .module('app', [])
    .directive('breadcrumb', function() {
        return {
            restrict: 'E',
            template: "<ul class='breadcrumb'><li ng-repeat='node in path'><a ng-href='{{node.url}}'>{{node.label}}</a></li></ul>",
            replace: true,
            controller: Ctrl1
        }
    })
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/', { 
                template: '<h1>{{pgTitle}}</h1>', 
                controller: Ctrl2
            });
    }]);

コントローラー

function Ctrl1($scope) {
    $scope.path = [{
            label: 'Home',
            url: '#/'}];
    $scope.pgTitle = "Home"       
}
function Ctrl2($scope, $routeParams) {
    $scope.path = [{
            label: 'Home',
            url: '#/'},{
            label: 'Node 2',
            url: '#/node2'}];
    $scope.pgTitle = "Node 2"
}

Ctrl2で変更$scope.pathすると、breadcrumbディレクティブが更新されると思いますが、実際には発生していません。私はそれが彼らの相対的な範囲と関係があると信じなければなりません、しかし単にそれが何を見るのに十分によく理解していません。私は何十もの記事とStackOverflowの投稿を読みましたが、何が欠けているのかを知るのに十分な具体的なものはありません。

誰かが私を正しい方向に向けてくれることを願っています。

どうもありがとう!

nz

4

1 に答える 1

5

あなたのフィドルが機能しない理由は、(あなたが正しく識別したように)スコープの問題のためです。あなたCtrl1は、ディレクティブのスコープを制御するコントローラーです。pathディレクティブは、パスの配列であるという変数を探しています。そのスコープのパス変数を見ると、その中に1つの値しか含まれていないようです。

function Ctrl1($scope) {
    $scope.path = [{
            label: 'Home',
            url: '#/'}];
    $scope.pgTitle = "Home"       
}

pathここで、この変数を別のコントローラーで変更したいとしますCtrl2Ctrl2のスコープから「継承」のスコープを取得しようとしていると想定していますCtrl1。これを実現するには、最初にどの要素Ctrl2が定義されているかを確認します。その要素(html要素)は?の要素の子Ctrl1ですか?

HTMLから:

の要素Ctrl1<breadcrumb></breadcrumb>

の要素Ctrl2<div ng-view></div>

Ctrl2子になるにはCtrl1:HTML構造は次のようになります:

<breadcrumb>
    <div ng-view></div>
</breadcrumb>

コードにこの変更を加えても、まだ機能しません。これは、angularがディレクティブを見ると<breadcrumb>、そのノード内にあるものをどう処理するかがわからないためです。<breadcrumb>はhtmlノードです。ノードであるため、その中にコンテンツ/他のノードを含めることができます。このブレッドクラムノードをテンプレートに置き換えるときは、効果に対して角度のある指示も与える必要があります:「私の中に何かを見つけたら、ここに置いてください」。これがあなたのやり方です。

ディレクティブコードを次のように変更します。

.directive('breadcrumb', function() {
            return {
                restrict: 'E',
                template: "<div><ul class='breadcrumb'><li ng-repeat='node in path'><a ng-href='{{node.url}}'>{{node.label}}</a></li></ul><div ng-transclude></div></div>",
                replace: true,
                transclude : true,
                controller: Ctrl1
            }
    })

ここにはいくつかの違い/変更があります。

  1. ディレクティブオブジェクトにtranscludeという属性を追加し、trueに設定しました。
  2. テンプレート全体をラップして、単一のHTML要素として返すことができるようにします。
  3. の内容を移動する場所を指定します。ng-transcludeに注目してください。そこが中身の行き先です。

コンテンツが置き換えられていることに気付くでしょう。パスが子コントローラからのパス値で更新されていないことを除いて。このhttps://stackoverflow.com/a/14049482/1057639の回答をご覧ください。これは、スコープ/典型的な継承の驚くべき説明です。基本的に、パスへの書き込みは、親パス(ディレクティブで使用されている)を覆い隠す新しいパス変数を子スコープに作成します。

このシナリオでの最善の策は、親スコープでaddPath関数を作成し、それを(子スコープで)使用して、新しいサブビューを定義するときに新しいパスを追加することです。

これらすべてを行うフィドルがあります。

于 2012-12-28T16:49:14.800 に答える