Transclude function needs to modify clone properly

时光怂恿深爱的人放手 提交于 2019-12-11 08:18:13

问题


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.

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

    });

});

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

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.

EDIT:

Added a plunkr here:

https://plnkr.co/edit/XE7REjJRShw43cpfJCh2

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.


回答1:


So here's a plunkr with I thinnnnk gets at what you're trying to do: https://plnkr.co/edit/8VxNPVmeLNLKyaQNReM3?p=preview

Note these lines in particular:

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>

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:

the two way binding definitions

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

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.



来源:https://stackoverflow.com/questions/38249445/transclude-function-needs-to-modify-clone-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!