javascript - Transclude函数需要适当修改clone

标签 javascript angularjs angularjs-ng-transclude transclusion

我有一个简单的指令,它将嵌入内容的一部分重复两次。像这样。

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

});

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

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

因此,我尝试修改代码来查找表单并将表单名称更改为新的名称,如下所示。

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。

问题是我的主 Controller 中仍然只有一个对 myForm 的引用。第一个有效,但第二个无效。我只能假设它们是以某种方式针对scope.$parent 进行编译的,在我弄乱克隆之前,我将其传递到transinclude 函数中?如果是这种情况,我不知道如何解决它。

编辑:

在这里添加了一个plunkr:

https://plnkr.co/edit/XE7REjJRShw43cpfJCh2

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

最佳答案

所以这是一个我认为的 plunkr 可以了解你想要做的事情: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 是正常的双向绑定(bind),可以绑定(bind)到您选择的范围属性,在我的示例中,myForm1myForm2

JS:

两种方式绑定(bind)定义

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

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

    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 因为 Angular form指令are not dynamic 。因此,手动查找 html 元素并将名称从 myForm 更改为 myForm2 不会更改绑定(bind)到范围的表单名称,除非 html 尚未编译。但是the clone passed to transclude has been freshly compiled .

关于javascript - Transclude函数需要适当修改clone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38249445/

相关文章:

javascript - 开 Jest - expect(...).toContainEqual 不是一个函数

javascript - 为什么 Angular 使用闭包来定义指令和其他核心语法?

javascript - 点击greymonkey中的按钮

javascript - 在nodejs的PUT方法中设置ID

javascript - Ember AppKit 和使用 ember 数据的嵌入对象

angularjs - 如何确保服务中的 $http.get 在指令用数据初始化之前完成?

javascript - 在模板中非法使用 ng-Transclude 指令

javascript - 尽管 ng Include angularjs 不会显示 html 父内容

javascript - 编译嵌入模板

angularjs - AngularJS 的可重用 docker 镜像