简体   繁体   English

AngularJS-从父控制器运行子控制器的功能

[英]AngularJS - Run function of child controller from parent controller

I have read many questions on this but still can't find solution that will be clean and reusable enough. 我已经读过很多问题,但是仍然找不到足够干净且可重用的解决方案。

What I tried and don't want to use: 我尝试过并且不想使用的内容:

  • Events - $emit and $broadcast, 活动-$ emit和$ broadcast,
  • DOM manipulation - for example angular.element('nameOfElement').scope() to access scope of child, DOM操作-例如angular.element('nameOfElement')。scope()访问子级范围,
  • $onChange in child component $ on更改子组件

Simple example 简单的例子

I've build simplified scenario of to present the problem. 我已经建立了简化的方案来提出这个问题。

On page there is TimerComponent that shows minutes and seconds. 在页面上有显示分钟和秒的TimerComponent It have controller TimerController to change its state: start() and stop() . 它具有控制器TimerController来更改其状态: start()stop() In example there are two of them, both presenting different values. 在示例中,有两个,它们都呈现不同的值。

Timer template does not contain buttons to manipulate it - that is intentional . 计时器模板不包含用于操作它的按钮- 这是有意的 I want to start and stop the timer from other controller. 我想从其他控制器启动和停止计时器。

Child-To-Parent communication . 亲子沟通 I can pass value and function callback onTick() that will be run every second. 我可以传递将每秒运行的value和函数回调onTick()

Parent-To-Child communication : How could I run start() or stop() functions from parent component? 亲子沟通 :如何从父组件运行start()或stop()函数?

timer.component.js timer.component.js

(function() {
    'use strict';

    TimerController.$inject = ['$interval']
    function TimerController($interval) {
        var ctrl = this;

        var interval = undefined;

        ctrl.start = start;
        ctrl.stop = stop;
        ctrl.minutes = minutes;
        ctrl.seconds = seconds;           

        function minutes() {
            return Math.floor(ctrl.value / 60);
        }

        function seconds() {
            return (ctrl.value % 60);
        }

        function start() {
            interval = $interval(function() {
                ctrl.value--;
                ctrl.onTick({ 'value': ctrl.value });
            }, 1000);
        }

        function stop() {
            $interval.cancel(interval);
        }
    }

    angular.module('app').component('timer', {
        bindings: {
            value: '<',
            onTick: '&'
        },

        templateUrl: 'timer.html',
        controller: TimerController
    });
})();

timer.html timer.html

<span ng-bind="$ctrl.minutes() + ':' + $ctrl.seconds()"></span>

app.html app.html

<body ng-app="app" ng-controller="MainController as vm">
    <p>First timer: </p>
    <timer value="360" on-tick="vm.firstTimerTick(value)"></timer>

    <p>Second timer: </p>
    <timer value="120" on-tick="vm.secondTimerTick(value)"></timer>

    <p>
        <span ng-click="vm.startFirstTimer()">Start first timer</span>
    </p>
</body>

main.controller.js main.controller.js

(function() {
    'use strict';

    angular.module('app').controller('MainController', MainController);

    function MainController() {
        var ctrl = this;
        ctrl.firstTimerTick = firstTimerTick;
        ctrl.secondTimerTick = secondTimerTick;
        ctrl.startFirstTimer = startFirstTimer;

        function firstTimerTick(value) {
            console.log('FirstTimer: ' + value);
        }

        function secondTimerTick(value) {
            console.log('SecondTimer: ' + value);
        }

        function startFirstTimer() {
            /* How to run start() function of TimerController here? */
        }

        function stopFirstTimer() {
            /* How to run start() function of TimerController here? */
        }
    }
})();

One approach is to use the new ngRef directive : 一种方法是使用新的ngRef指令

<timer ng-ref="vm.timerOne" value="360" on-tick="vm.firstTimerTick(value)">
</timer>

Then use it in the controller: 然后在控制器中使用它:

function startFirstTimer() {
    /* How to run start() function of TimerController here? */
    ctrl.timerOne.start();
}

The ngRef directive was introduced as a new feature with AngularJS V1.7.1 . ngRef指令AngularJS V1.7.1的新增功能。

For more information, see AngularJS ng-ref Directive API Reference . 有关更多信息,请参见AngularJS ng-ref Directive API Reference

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从angularjs中的子控制器调用父控制器中的函数 - How to call function in parent controller from the child controller in angularjs 从父控制器调用子控制器中的函数 - Calling function in child controller from parent controller AngularJS从子控制器访问父作用域 - AngularJS access parent scope from child controller 从子[angularjs]将数据推送到父控制器 - Push data to parent controller from child [angularjs] 使用AngularJs ControllerAs方法,如何从子控制器中调用父控制器中的函数? - Using AngularJs ControllerAs approach, How can I call a function in a parent controller from the child controller? 如何在 AngularJS 中将数据从子控制器发送到父控制器? - How to send data from child controller to Parent controller in AngularJS? 从AngularJS的父控制器上的子控制器访问Fileitem - Access fileitem from child controller on parent controller in AngularJS 如何:AngularJS - 从子控制器访问父控制器中的方法 - How To: AngularJS - Access method in parent controller from child controller AngularJS-使用controllerAs表示法从child-&gt; child指令访问父控制器 - AngularJS - Access a parent controller from child -> child directive with the controllerAs notation 从父视图调用的子控制器中的函数 - function in child controller called from parent view
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM