AngularJS 组件动态编译不向上传递事件

AngularJS Dynamic compilation of component not passing events up

我正在使用模式来显示呈现给用户的表单。表单都是带有 onSave 和 onCancel 方法的组件

  bindings: {
        entity: '<',
        readOnly: '<',
        onSave: '&',
        onCancel: '&'
    },

我想将要在模态中显示的表单标签传递给模态,然后将由组件的 onSave/onCancel 事件编辑的参数 return 传递回模态,这将 return 它给调用者。为此,我放置了一个设置组件属性的指令,然后通过 $compile 方法运行它以生成它:

 function link(scope, elem, attrs) {
        if (scope.formType != null && scope.formType != '') {
            var objString = "<" + scope.formType + " "; //create beginning tag
            objString += "entity='assignedEntity' read-only='readOnly' ";
            objString += "on-save='onSave(entity)' on-cancel='onCancel(entity)'>";
            objString += "</" + scope.formType + ">"; //add end tag

            var obj = $compile(objString)(scope);

            elem.append(obj);
        }
    };

    return {
        restrict: 'E',
        scope: {
            formType: '=',
            onSave: '&',
            onCancel: '&',
            assignedEntity: '<',
            readOnly: '<'
        },
        link: link
    }

然后我调用指令并从通用模式框传递适当的属性,如下所示:

 <form-generator 
                form-type="vm.ui.properties.formType"
                on-save="vm.ok(entity)"
                on-cancel="vm.cancel(entity)"
                assigned-entity="vm.returnItem.entity"
                read-only="vm.ui.properties.readOnly">
            </form-generator>

这成功生成了指定的表单组件,并将每个 属性 的正确值传递给表单组件。我的问题是,当组件抛出 onSave 或 onCancel 事件时,模态控制器正在接收事件(调用 vm.ok 或 vm.cancel)但传递给这些事件的参数不会传递电话。传递给 vm.ok 和 vm.cancel 的属性始终未定义。

在组件中,我这样调用 onSave/onCancel 方法:

  ctrl.onSave({
            entity: ctrl.entity
        });

并且我已经验证 ctrl.entity 实际上确实有价值。

关于为什么传递回调用树的参数在到达模态控制器时未定义的任何想法?

我创建了这个 plunkr 来帮助定义我遇到的问题:Example

请查看代码,经过一些调试后,您似乎只是忘记将实体作为监听 click $event 的函数的一部分附加。这是工作 plunker.

(function() {

  var directiveID = "formGenerator";

  angular.module('app').directive(directiveID, ['$compile', FormGenerator]);

  function FormGenerator($compile) {

    function link(scope, elem, attrs) {
      console.log(scope, elem, attrs);
      if (scope.formType !== null && scope.formType !== '') {
        var objString = "<" + scope.formType + " "; //create beginning tag
        //PLEASE TAKE A LOOK HERE, WE'RE EXPECTING THE EVENT TO PROPOGATE TO THE PARENT CONTROLLER
        //so we take into account the event on-save, the same would have to be done for on-cancel
        objString += "on-save='onFormSave($event)' on-cancel='onFormCancel(entity)'>";
        objString += "</" + scope.formType + ">"; //add end tag

        var obj = $compile(objString)(scope);

        elem.append(obj);
      }
    }

    return {
      restrict: 'E',
      scope: {
        formType: '=',
        onFormSave: '&',
        onFormCancel: '&'
      },
      link: link
    }
  }
})();




(function() {
  var componentID = "testForm";

  var app = angular.module("app");

  function TestFormController() {
    var ctrl = this;

    ctrl.entity = {
      name: "this is the entity passed up"
    };

    ctrl.save = function(event) {
      console.log(event);
      console.log("In component: " + ctrl.entity.name);
      ctrl.onSave({
        //AND ON SAVE, we make the this controllers model-properties which you'd like to pass on a part of the event.
        $event: {
          entity: ctrl.entity
        }
      });
    };

    ctrl.cancel = function() {
      ctrl.onCancel({
        entity: ctrl.entity
      });
    };
  }

  app.component(componentID, {
    bindings: {
      onSave: '&',
      onCancel: '&'
    },
    //Here also we pass the $event to function
    template: '<h1> This is a test</h1><button type="button" ng-click="$ctrl.save($event);">Save</button>',
    controller: TestFormController
  })

}());