2016-08-11 9 views
0

ここに問題があります。私はメインディレクティブと呼ばれる第三者指令を持っています。AngularJS指令コントローラ機能を無効にします

app.directive('mainDirective', function() { 
    return { 
    scope: { 
     foo: '&' 
     // attrs 
    }, 
    controller: function($scope) { 

     $scope.click = function() { 
     window.alert($scope.foo()); 
     } 

    }, 
    template: '<button ng-click="click()">Click me</button>' 
    } 
}); 

だから私は自分のディレクティブを作りたいが親ディレクティブ第三者ディレクティブの属性にアプリケーション固有のデフォルト値を割り当てると呼ばれます。私は別の子ディレクティブ親ディレクティブロジックを保持したい場合はどう

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     foo: '&?', 
     attr2: '=' 
     // lots of attrs 
    }, 
    controller: function($scope) { 


     $scope.attr1 = "some default value" 

     $scope.foo = function() { 
     return "not overrided" 
     } 

     if (this.foo) { 
     $scope.foo = this.foo 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()" attr1="attr1" attr2="attr2"></main-directive></div>' 
    } 
}); 

。 属性のオーバーロードは簡単です。「コンパイル」機能を使用できます。しかし、関数のオーバーライドは可能ですか?

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function(scope, element, attr, controller) { 

     controller.foo = function() { 
     return "overrided"; 
     } 

    }, 
    compile: function(element, attr) { 
     attr.attr2 = "attr2"; 
    } 
    } 
}); 

隔離されているのではなく、子スコープを使用することで簡単に行うことができます。 またはテンプレートを使用して拡張を使用します。しかし、テンプレートを使ってディレクティブを拡張すると、親 "スコープ"と "テンプレート"の定義を子ディレクティブにコピーし、これ以外のすべての非デフォルト属性を転送する必要があります。

重要な質問は、属性を転送せずに分離スコープを使用して親ディレクティブ機能をオーバーライドする方法です。ここで

DEMO

+0

$ parentを使ってみましたか?あなたの関数が親スコープ内にある場合は、$ parentを使ってその関数にアクセスすることができます。 – acostela

+0

確かに、ng-if指令が親と子の間のどこかにあればどうでしょうか? $ parentを使うIMHOはここでの解決策ではありません。 $ parentが悪い習慣とみなされるという事実にもかかわらず。 – dagi12

答えて

0

OKですが、私はいくつかの研究を行っている、それはそこにいくつかのアプローチがあり得ることが判明し

スコープ継承子-ディレクティブは、独自に作成されていないので

スコープは、親ディレクティブの親スコープで新しいメソッドを作成するだけです。したがって、コンパイル時に属性を変更し、オーバーライドされたfooメソッドを指定することができます。ここで

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     $scope.foo = function() { 
     if ($scope.fooImpl) { 
      return $scope.fooImpl(); 
     } 
     return "not overrided"; 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    controller: function($scope) { 

     $scope.foo = function() { 
     return "overrided"; 
     } 

    }, 
    compile: function(element, attr) { 
     attr.fooImpl = "foo()"; 
    } 
    } 
}); 

は、特別な機能を提供しDEMO1

が孤立スコープ

角に追加されます。それは要素から分離されたスコープを得ることができます。そこで、リンクフェーズ中にメソッドをオーバーライドすることができます。我々はcontrollerAs構文を使用する場合はここで

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     $scope.foo = function() { 
     if ($scope.fooImpl) { 
      return $scope.fooImpl(); 
     } 
     return "not overrided"; 
     } 

    }, 
    template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function(scope, element, attr) { 
     var innerScope = angular.element(element[0]).isolateScope(); 
     innerScope.foo = function() { 
     return "overrided"; 
     } 
    } 
    } 
}); 

DEMO2

コントローラメソッド

です。これは、コントローラオブジェクト変数をスコープとして公開することを意味します。リンクフェーズ中に子ディレクティブの関数をオーバーライドすることができます。ここで

app.directive('parentDirective', function() { 
    return { 
    scope: { 
     fooImpl: '&?', 
     // lots of attrs 
    }, 
    controller: function($scope) { 

     var vm = this; 

     vm.foo = function() { 
     return "not overrided"; 
     } 

    }, 
    controllerAs : 'vm', 
    template: '<div class="some-styling"><main-directive foo="vm.foo()"></main-directive></div>' 
    } 
}); 

app.directive('childDirective', function() { 

    return { 
    scope: false, 
    require: 'parentDirective', 
    link: function (scope, element, attr, controller) { 

     controller.foo = function() { 
     return "overrided"; 
     } 


    } 
    } 
}); 

DEMO3

トランスクルー

で実際にあなたが別々の親と子のディレクティブとトランスクルーを使用して同じことを行うことができます。しかし、とにかくそれは上記のアプローチの組み合わせになります。ありがとう"Extending an existing directive in AngularJS"

関連する問題