AngularJS - запускать функцию дочернего контроллера от родительского контроллера

Я прочитал много вопросов по этому поводу, но все еще не могу найти решение, которое было бы достаточно чистым и пригодным для повторного использования.

Что пробовал и не хочу использовать:

  • События - $ emit и $ broadcast,
  • Манипуляции с DOM - например, angular.element ('nameOfElement'). Scope () для доступа к области дочернего элемента,
  • $ onChange в дочернем компоненте

Простой пример

Я построил упрощенный сценарий, чтобы представить проблему.

На странице есть TimerComponent, который показывает минуты и секунды. У него есть контроллер TimerController для изменения своего состояния: start() и stop(). В примере есть два из них, оба представляют разные значения.

В шаблоне таймера нет кнопок для управления им - это намеренно. Я хочу запускать и останавливать таймер с другого контроллера.

Общение между родителями и детьми. Я могу передать value и функцию обратного вызова onTick(), которая будет запускаться каждую секунду.

Общение между родителями и детьми: Как мне запустить функции start () или stop () из родительского компонента?

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

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

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

(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.info('FirstTimer: ' + value);
        }

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

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

        function stopFirstTimer() {
            /* How to run start() function of TimerController here? */
        }
    }
})();
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Директивы позволяют расширять HTML новыми элементами и атрибутами и даже создавать собственные структурные директивы для манипулирования DOM. С...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
0
0
203
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из подходов - использовать новый директива ngRef:

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

Затем используйте его в контроллере:

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

директива ngRef был представлен как новая функция с AngularJS V1.7.1.

Для получения дополнительной информации см. Справочник по API директивы AngularJS ng-ref.

Другие вопросы по теме