Передать объект в родительскую область видимости директивы Angular

Как можно было бы передать объект Angular's (Angular 1.4.8) & Обязательная директива об амперсанде?

Из документов я понимаю, что существует некоторая деструктуризация ключей, которая требует именованных параметров в функции обратного вызова, и родительская область использует эти имена в качестве аргументов. Этот SO ответ дает полезный пример ожидаемого & функциональность. Я могу заставить это работать, когда явно называю параметры при вызове функции родительского контроллера.

Тем не менее, я использую & выполнять действия через фабрику. Родительский контроллер ничего не знает о параметрах и просто передает параметры обратного вызова в dataFactory, которому нужны различные ключи / значения в зависимости от действия.

Как только обещание разрешается на фабрике, родительская область обновляется возвращенными данными.

Как таковой, мне нужен объект с n количество пар ключ / значение, а не именованных параметров, поскольку оно будет варьироваться в зависимости от каждого настроенного действия. Это возможно?

Самое близкое, что я видел, - это ввести $ parse в функцию ссылки, которая не отвечает на мой вопрос, но является своего рода обходным решением, которое я ищу. Этот вопрос без ответа звучит так же, как мне нужно.

Кроме того, я пытаюсь избежать кодирования / декодирования JSON, и я хотел бы избежать broadcast как хорошо, если это возможно. Код сокращен для краткости. Спасибо...

Relevant Child Directive Code

function featureAction(){
    return {
        scope: true,
        bindToController: {
            actionConfig: "=",
            actionName: "=",
            callAction: "&"
        },
        restrict: 'EA',
        controllerAs: "vm",
        link: updateButtonParams,
        controller: FeatureActionController
    };
}

Child handler on the DOM

 /***** navItem is from an ng-repeat, 
        which is where the variable configuration params come from *****/

ng-click="vm.takeAction(navItem)"

Relevant Child Controller

function FeatureActionController(modalService){
    var vm = this;
    vm.takeAction = takeAction;

    function _callAction(params){
        var obj = params || {};
        vm.callAction({params: obj});  // BROKEN HERE --> TRYING
                                       //TO SEND OBJ PARAMS
    }

    function executeOnUserConfirmation(func, config){
    return vm.userConfirmation().result.then(function(response){ func(response, config); }, logDismissal);
}

function generateTasks(resp, params){
    params.example_param_1 = vm.add_example_param_to_decorate_here;
    _callAction(params);
}

function takeAction(params){
    var func = generateTasks; 
    executeOnUserConfirmation(func, params);
}

Relevent Parent Controller

function callAction(params){
        // logs undefined -- works if I switch to naming params as strings
        console.log("INCOMING PARAMS FROM CHILD CONTROLLER", params) 
        executeAction(params);   
    }

    function executeAction(params){
        dataService.executeAction(params).then(function(data){ 
            updateRecordsDisplay(data); });
    }

1 ответ

Решение

Я думаю, что пример ниже должен дать вам достаточно начала, чтобы выяснить ваш вопрос:

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <meta charset="utf-8">
    <title>Angular Callback</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script>
    var myApp = angular.module("myApp", []);

    myApp.controller('appController', function($scope) {
      $scope.var1 = 1;

      $scope.handleAction1 = function(params) {
        console.log('handleAction1 ------------------------------');
        console.log('params', params);
      }

      $scope.handleAction2 = function(params, val1) {
        console.log('handleAction2 ------------------------------');
        console.log('params', params);
        console.log('val1', val1);
      }

    });


    myApp.controller('innerController', innerController);
    innerController.$inject = ['$scope'];
    function innerController($scope) {
      $scope.doSomething = doSomething;

      function doSomething() {
        console.log('doSomething()');
        var obj = {a:1,b:2,c:3}; // <-- Build your params here
        $scope.callAction({val1: 1, params: obj});
      }
    }

    myApp.directive('inner', innerDirective );
    function innerDirective() {
      return {
        'restrict': 'E',
        'template': '{{label}}: <button ng-click="doSomething()">Do Something</button><br/>',
        'controller': 'innerController',
        'scope': {
          callAction: '&',
          label: '@'
        }
      };
    }
    </script>
  </head>
  <body ng-controller="appController">
    <inner label="One Param" call-action="handleAction1(params)"></inner>
    <inner label="Two Params" call-action="handleAction2(params, val)"></inner>
  </body>
</html>

в appController У меня есть две функции, которые будут вызываться inner директивы. Директива ожидает, что внешний контроллер передаст эти функции, используя call-action атрибут на <inner> тег.

Когда вы нажимаете на кнопку внутри inner Директива это называется функцией $scope.doSomething Это, в свою очередь, вызывает функцию внешнего контроллера handleAction1 или же handleAction2, Он также передает набор параметров val1 а также params:

$scope.callAction({val1: 1, params: obj});

В своем шаблоне вы указываете, какой из этих параметров вы хотите передать в функцию внешнего контроллера:

call-action="handleAction1(params)"

или же

call-action="handleAction2(params, val)"

Затем Angular использует эти имена параметров для просмотра объекта, который вы отправили при вызове. $scope.callAction,

Если вам нужны другие параметры, передаваемые во внешнюю функцию контроллера, просто добавьте их в объект, определенный в вызове $scope.callAction, В вашем случае вы хотели бы поместить больше контента в объект, который вы передаете:

var obj = {a:1,b:2,c:3}; // <-- Build your params here

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

Если это не то, что вы спрашивали, дайте мне знать.

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