2016-05-17 42 views
2

我建立一個簡單的視圖的事件:AngularJS組件綁定的函數,而不是發射

<tabulation tabulation-data="vm.tabs"></tabulation> 

<div ng-switch="vm.activeTab.id"> 
    <account-details ng-switch-when="details"></account-details> 
    <account-history ng-switch-when="history"></account-history> 
    <account-summary ng-switch-when="summary"></account-summary> 
    <account-dashboard ng-switch-when="dashboard"></account-dashboard> 
</div> 

本質上,如我現在工作,製表將$emit一個事件到母體account控制器,該控制器將更新vm.activeTab屬性來切換不同的標籤內容。

我的一個同事告訴我,這可能是更優雅的tabulation組件,這將使用由父account組件通過了功能上的使用綁定(&)...

不幸的是,我不知道縫,以便了解其功能:

家長account控制器:

function PocDemoContainerController($scope) { 
    var vm = this; 

    vm.tabs = [{ 
     label: 'Details', 
     id: 'details' 
    }, 
    { 
     label: 'History', 
     id: 'history' 
    }, 
    { 
     label: 'Summary', 
     id: 'summary' 
    }, 
    { 
     label: 'Dashboard', 
     id: 'dashboard' 
    }]; 

    vm.activeTab = vm.tabs[0]; 

    // this is the function that I want to pass to the tabulate component 
    vm.onClickTab = function (tab) { 
     vm.activeTab = tab; 
    }; 

    ... 
} 

TABULATE組件的HTML:

<tabulation tabulation-data="vm.tabs" on-click-tab="vm.onClickTab(tab)"> 
<div class="tabulation"> 

    <nav class="container"> 
     <button class="tabulation__mobile-toggle" 
       ng-class="{'tabulation__mobile-toggle--is-open': vm.mobileTabulationIsOpen}" 
       ng-click="vm.toggleMobileTabulation()">{{vm.activeTab.label}}</button> 

     <ul class="tabulation__container" 
      ng-class="{'tabulation__container--is-open': vm.mobileTabulationIsOpen}"> 

      <li class="tabulation__item" 
       ng-repeat="tab in vm.tabs" 
       ng-class="{'tabulation--is-active': vm.isTabActive(tab)}"> 

       <a id={{tab.id}} 
        class="tabulation__link" 
        ng-click="vm.onClick(tab)">{{tab.label}}</a> 
      </li> 
     </ul> 
    </nav>  
</div> 
</tabulation> 

TABULATE控制器:

... 

module.exports = { 
    template: require('./tabulation.html'), 
    controller: TabulationController, 
    controllerAs: 'vm', 
    bindings: { 
     tabulationData: '<', 
     onClickTab: '&' // this should send data up, right? 
    } 
}; 

製表控制器:

function TabulationController($scope) { 
    var vm = this; 

    ... 

    vm.onClick = function (tab) { 
     vm.onClickTab(tab); // This is the function from the parent I want to call 
    }; 

    ... 
} 

TabulationController.$inject = [ 
    '$scope' 
]; 

module.exports = TabulationController; 

因此,tabulation控制器可以看到和撥打vm.onClickTab但正在傳遞沒有傳遞給父參數值account組件控制器...

我該如何實現這是嗎? (這是甚至有可能嗎?)

+0

做你的指令控制器:'vm.onClickTab({tab:tab});' – devqon

+0

@devqon不幸的是,這是行不通的。這就是我得到的'Object {tab:undefined}'。 – justinledouxweb

回答

0

看着你的Tabular組件html我不知道你要發送的參數是tab。它是你的控制器的本地屬性嗎?這似乎不是因爲它沒有前綴(或其他任何你已經定義的名稱)的vm。你的代碼似乎是合法的,它的參數起源不明確,因此未定義。 給我們一個關於其來源的提示以供進一步分析。

+0

這就是我想弄清楚的......在角度組件文檔中,他們使用這種形式......但我也不明白這個值來自哪裏。 – justinledouxweb

+0

讓我看看我是否正確理解你 - 當點擊「製表」元素時,你想要將製表標識(或其他唯一值)傳遞給回調函數,對嗎?如果是這種情況,您必須傳遞某個值,可以是此標籤的索引值或ID。父控制器將使用此Id從其選項卡陣列中選擇正確的選項卡(如果這是您實施的設計)。 – AranS

+0

是的,你瞭解目標。這就是代碼目前正在做的事情。如果你看看'TabulationController'中的'vm.onClick'方法,你會發現它正在調用回調函數並傳遞tab對象。問題是父控制器得到的未定義。 – justinledouxweb

9

好吧!我終於找到了如何去做,而且一點也不直觀(角度文檔並沒有告訴你這一點)。

基於上面的例子,我的製表需要告訴父組件,哪個標籤現在處於活動狀態,以便它可以更新視圖。

方法如下:

  • 聲明你的父組件上的功能:
    • vm.onClickTab = function (tab) { ... };
  • 把功能時,您的孩子組件。
    • <tabulation on-click-tab="vm.onClickTab(tab)"
    • 重要:如果您傳遞一個參數,使用相同的名稱作爲一個你會在你的子組件定義。
  • 在你的子組件裏面,聲明一個新函數,它是那個應該調用父進程回調的函數。
    • vm.onClick = function (tab) { ... };
  • 現在,這裏來是沒有在任何地方提到的部分:你必須使用一個對象調用父的回調函數,與使用傳遞一個回調時所定義的相同名稱的屬性孩子的組成部分:

function TabulationController($scope) { 
    ... 
    vm.onClick = function (tab) { 
     // The onClickTab() function requires an object with a property 
     // of "tab" as it was defined above. 
     vm.onClickTab({tab: tab}); 
    }; 
    ... 
} 
  • 現在,當vm.onClick()被調用時,它調用父類的回調與對象,通過它的說法,和家長現在可以使用這些數據來更新視圖。
+0

或者,通過單向綁定傳遞迴調。請參閱http://blog.krawaller.se/posts/dissecting-bindings-in-angularjs/或討論。 –