Transclude函数需要正确修改克隆 [英] Transclude function needs to modify clone properly

查看:108
本文介绍了Transclude函数需要正确修改克隆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple directive which repeats a section of transcluded content twice. Like this.

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);
    });

});

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

This works mainly as intended but if the content contains a form then I end up with two forms with the same name.

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

More importantly my main page controller (customers) only has reference to one of the forms (customers.myForm) so if I try to reset the form or call any other form controller functions only one of the forms changes, obviously.

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

So, I tried to modify my code to look for forms and change the form name to something new, like this.

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。

This does actually modify the HTML for me and I end up with two forms - myForm and myForm2.

问题是在我的主控制器中仍然只有一个对myForm的引用。第一个有效,但第二个无效。我只能假设它们是在一定范围内针对范围编译的。$ parent在弄乱克隆之前要传递给transclude函数吗?如果是这种情况,我不确定如何解决。

The problem is that there is still only one reference to myForm in my main controller. The first one works but the second one doesn't. I can only assume that they are somehow compiled against the scope.$parent which I'm passing into the transclude function before I'm messing about with the clone? If that's the case I'm not sure how to fix it.

编辑:

在此处添加了plunkr:

Added a plunkr here:

https:// plnkr.co/edit/XE7REjJRShw43cpfJCh2

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

If you open a dev console you'll see that I'm using console.log to write out the contents of myForm and myForm2 which should be the two copies of the form in my second toolbar. myForm2 doesn't exist and I suspect this is because it's compiled against the parent scope before it's cloned.

推荐答案

所以这是一个插件与我Thinnnnk会得到您想要做的事情: https://plnkr.co/edit / 8VxNPVmeLNLKyaQNReM3?p = preview

So here's a plunkr with I thinnnnk gets at what you're trying to do: 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-one form-two 是正常的双向绑定,可以绑定到您选择的范围属性我的示例是 myForm1 myForm2

note that both name attributes point at the same string "myForm". form-one and form-two are normal two way bindings that can be bound to your scope properties of choosing, in my example, myForm1 and myForm2.

JS:

双向绑定定义

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

并将这两种新形式绑定到各自的作用域属性:

and binding the two new forms to respective scope attributes:

    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 的克隆 已重新编译

Looking back at your code, this console console.log("myForm", $scope.myForm2) printed undefined because angular form directives are not dynamic. As a result, manually finding the html element and changing the name from myForm to myForm2 will not change the name of the form bound to scope unless the html has yet to be compiled. But the clone passed to transclude has been freshly compiled.

这篇关于Transclude函数需要正确修改克隆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆