排除功能需要正确修改克隆



我有一个简单的指令,它重复了一段被排除的内容两次。喜欢这个。

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 的引用。第一个有效,但第二个无效。我只能假设它们是针对范围以某种方式编译的,$parent我在弄乱克隆之前将其传递到transclude函数中?如果是这种情况,我不确定如何解决它。

编辑:

在这里添加了一个 plunkr:

https://plnkr.co/edit/XE7REjJRShw43cpfJCh2

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

所以这里有一个 plunkr 与 I thinnnnk 了解你想做的事情: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指令不是动态的。因此,手动查找 html 元素并将名称从 myForm 更改为 myForm2 不会更改绑定到作用域的表单的名称,除非尚未编译 html。但传给transclude clone是新编的。

最新更新