AngularJS 组件绑定(bind)一个函数而不是发出一个事件

标签 angularjs

我正在构建一个简单的 View :

<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给 parent 的事件account Controller ,它将更新 vm.activeTab属性来切换不同的选项卡内容。

我的一位同事告诉我,在 tabulation 上使用绑定(bind) (&) 可能更优雅。组件,它将使用父 account 传递的函数零件...

不幸的是,我不明白它是如何运作的:

家长 account Controller :
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;
    };

    ...
}

列表组件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>

制表 Controller :
...

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

制表 Controller :
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 Controller 可以看到并调用vm.onClickTab但是正在传递的参数值没有传递给父 account组件 Controller ...

我如何实现这一目标? (甚至有可能吗?)

最佳答案

好的!我终于找到了怎么做,它一点也不直观( Angular 文档没有告诉你这个)。

基于上面的示例,我的制表需要告诉父组件哪个选项卡现在处于事件状态,以便它可以更新 View 。

方法如下:

  • 在父组件上声明一个函数:
  • 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()被调用时,它用一个对象调用父级的回调,将参数传递给它,父级现在可以使用该数据来更新 View 。
  • 关于AngularJS 组件绑定(bind)一个函数而不是发出一个事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37278051/

    相关文章:

    javascript - AngularJS 指令只调用一次?

    javascript - 调试 : ng-click and non-existent functions

    javascript - Kendo + Angular 图表数据

    javascript - Angular 事件触发后 DOM 不会更新是不同的 Controller

    Angularjs 中止的 promise 仍然延迟其他 promise

    javascript - Angular 1.5 将带有参数的函数传递给组件?

    javascript - AngularJS ng-仅包含一次

    javascript - ViewContainerRef 未将组件加载到 DOM 中

    angularjs - Ionic 3 - 异步 Http 调用和 Ionic 加载问题

    javascript - 单个 View 上的多个 ng-repeat