我有一个简单的指令,该指令将一段被包含的内容重复两次。像这样。

link: function (scope, element, attrs, controller, transclude) {

    transclude(scope.$parent, function(clone) {
        element.find('[transclude-main]').replaceWith(clone);
    });

    transclude(scope.$parent, function(clone) {
        element.find('[transclude-overflow]').replaceWith(clone);
    });

});


这主要是按预期工作的,但是如果内容包含一个表单,那么我最终会得到两个具有相同名称的表单。

更重要的是,我的主页控制器(客户)仅引用其中一种表单(customers.myForm),因此,如果我尝试重置表单或调用任何其他表单控制器功能,显然只有一种表单更改。

因此,我试图修改代码以查找表单并将表单名称更改为新的名称,例如这样。

link: function (scope, element, attrs, controller, transclude) {

    transclude(scope.$parent, function(clone) {
        element.find('[transclude-main]').replaceWith(clone);
    });

    transclude(scope.$parent, function(clone) {

        clone.find('FORM').each(function() {
            $(this).attr('name', $(this).attr('name') + '2');
        });
        element.find('[transclude-overflow]').replaceWith(clone);

    });

});


实际上,这确实为我修改了HTML,最终我得到了两种形式-myForm和myForm2。

问题是在我的主控制器中仍然只有一个对myForm的引用。第一个有效,但第二个无效。我只能假设它们是在一定范围内针对scope。$ parent进行编译的,然后才将其传递给transclude函数。如果是这种情况,我不确定如何解决。

编辑:

在此处添加了一个plunkr:

https://plnkr.co/edit/XE7REjJRShw43cpfJCh2

如果打开开发者控制台,您会看到我正在使用console.log来写出myForm和myForm2的内容,它们应该是第二个工具栏中表单的两个副本。 myForm2不存在,我怀疑这是因为它是在克隆之前针对父作用域进行编译的。

最佳答案

因此,这是我的一个笨拙的人,您可以尝试执行以下操作:https://plnkr.co/edit/8VxNPVmeLNLKyaQNReM3?p=preview

请特别注意以下几行:

HTML:

  <toolbar name="myForm" form-one="myForm1" form-two="myForm2">
    <form name="myForm" submit="appController.submit()">
      Search:<br />
      <input type="text" ng-model="appController.searchText" />
    </form>
  </toolbar>


请注意,两个name属性都指向相同的字符串"myForm"form-oneform-two是正常的双向绑定,可以绑定到您选择的范围属性(在我的示例中为myForm1myForm2)。

JS:

双向绑定定义

    scope: {
      formOne: '=',
      formTwo: '='
    },


并将这两个新表单绑定到各自的范围属性:

    link: function (scope, element, attrs, controller, transclude) {

        var parent = scope;

        transclude(function(clone, scope) {
            element.find('[transclude-main]').replaceWith(clone);
            var unwatch = scope.$watch(attrs.name, function(form) {
              if (form) {
                parent.formOne = form;
                unwatch();
              }
            });
        });

        transclude(function(clone, scope) {
            element.find('[transclude-overflow]').replaceWith(clone);
            var unwatch = scope.$watch(attrs.name, function(form) {
              if (form) {
                parent.formTwo = form;
                unwatch();
              }
            });
        });


回顾您的代码,该控制台console.log("myForm", $scope.myForm2)打印undefined,因为角度form指令are not dynamic。结果,除非尚未编译html,否则手动查找html元素并将名称从myForm更改为myForm2不会更改绑定到范围的表单的名称。但是the clone passed to transclude has been freshly compiled

07-24 16:23