2017-10-09 6 views
0

私はtutorialの後に、AngularJSのsidenavでドロップダウンメニューを実装しています。私は私のレイアウトが提供されている例とは異なるので、アプリケーションでコンポーネントを使用しました。親コントローラの要素にアクセスできない

ulには、オブジェクトに格納されている名前が入力されていますが、機能が失敗しています。私は、ディレクティブの親要素のコントローラを見つけることができないためにエラーを解決するために絞り込んでいます。私はコンソールでcontrollerをログインすると

var controller = $element.parent().controller(); 

、それがされているコントローラの機能を表示する必要があります

vm.isOpen = isOpen; 
vm.toggleOpen = toggleOpen; 
vm.autoFocusContent = false; 
vm.menu = mainNavService; 
vm.status = { 
    isFirstOpen: true, 
    isFirstDisabled: false 
}; 

をしかし、その代わりに、それは戻って、空のオブジェクト。それはコントローラを使用するのではなく、モジュール上でAngularのコンポーネントメソッドを使用していて、コントローラプロパティを使用しているからですか?コントローラにアクセスしようとすると、それは何のプロパティを返さないのはなぜ

質問

app.component('mainnav', { 
    templateUrl: 'p3sweb/app/components/app/views/main-nav.htm', 
    controller: ['userService', 'mainNavService', function(userService, mainNavService){ 

     var vm = this; 

     vm.isOpen = isOpen; 
     vm.toggleOpen = toggleOpen; 
     vm.autoFocusContent = false; 
     vm.menu = mainNavService; 
     vm.status = { 
      isFirstOpen: true, 
      isFirstDisabled: false 
     }; 
     function isOpen(section) { 
      console.log('menu.isSectionSelected(section)') 
      return menu.isSectionSelected(section); 
     } 
     function toggleOpen(section) { 
       console.log(menu.toggleSelectSection(section)) 
      menu.toggleSelectSection(section); 
     } 
    }] 
}) 

app.directive('menuToggle', [ '$timeout', function($timeout){ 
    return { 
     scope: { 
      section: '=' 
     }, 
     templateUrl: 'p3sweb/app/components/app/views/main-nav-li.htm', 
     link: function($scope, $element) { 

      var controller = $element.parent().controller(); //FAILS 

      $scope.isOpen = function() { 
       return controller.isOpen($scope.section) 
      }; 
      $scope.toggle = function() { 
       console.log(controller.toggleOpen()) 
       controller.toggleOpen($scope.section); 
      }; 
     } 
    }; 
}]) 
+0

であなたは 'mainnavを宣言しようとしなかったことを交換することを置き換える見つけるどこ'コンポーネントの代わりにディレクティブとして? –

+2

'mainnav'の' menuToggle'への参照を 'scope: {section: '='、context: '='}'のように渡さないのはなぜですか? あなたの ' – AdityaParab

+0

一般に、コンポーネントでは、親コントローラにアクセスするための受け入れられた方法は 'require'プロパティを使うことです。詳細については、[AngularJS開発者ガイド - インターコンポーネント通信](https://docs.angularjs.org/guide/component#intercomponent-communication) – georgeawg

答えて

1

javascriptのコンテキストはかなり簡単に周りに渡すことができます。あなたにできることは変化が、

app.directive('menuToggle', [ '$timeout', function($timeout){ 
    return { 
     scope: { 
      section: '=', 
      context: '=' // NOTE: This is what the parent component will pass 
     }, 
     templateUrl: 'p3sweb/app/components/app/views/main-nav-li.htm', 
     link: function($scope, $element) { 
      var controller = $scope.context; // This is reference to parent 
      $scope.isOpen = function() { 
       return controller.isOpen($scope.section) 
      }; 
      $scope.toggle = function() { 
       console.log(controller.toggleOpen()) 
       controller.toggleOpen($scope.section); 
      }; 
     } 
    }; 
}]) 

などの内部あなたのmenuToggleディレクティブでごmain-nav.htmあなたは$scope.isOpen$scope.toggleもある

<menu-toggle section="blah" context="$ctrl"></menu-toggle>

EDIT ::

機能を実行する必要があります不要。 (あなたがそれらをあなたが今持っている方法を持っているためにいくつかの特定の要件を持っていない限り)

あなた main-nav-li.htm

あなたはisOpen()context.isOpen(section)、あなたがtoggle()を持っているところはどこでも、とcontext.toggle(section)

+0

もう一度ありがとう! –

0

私はjsfiddleでコードを実行し、これは私が変更するものである:あなたがアクセスすることができます。この後

app.directive('mainnav', function(){ 
    return { 
     transclude: true, 
     template: '<div> <ng-transclude></ng-transclude> <div>', 
     controller: ['$scope', function($scope){ 
      var vm = this; 
      vm.autoFocusContent = false; 
      vm.status = { 
      isFirstOpen: true, 
      isFirstDisabled: false 
      }; 

     }] 
    } 
}); 

まず私はtranscludeオプションを追加するディレクティブにコンポーネントを変更しました親コントローラは次のようになります。

var controller = $element.parent().controller('mainnav'); 

完全な例は次のとおりです。

https://jsfiddle.net/jm65ajjz/2/

+0

私は例のために私のコードを細かくしたので、少し調整する必要がありますが、ありがとう、私は行くよ –

関連する問題