加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – Angular UI Modal中的Transclusion无法正常工作

发布时间:2020-12-17 06:51:31 所属栏目:安全 来源:网络整理
导读:this plunk的目标是将元素从控制器转换为Angular UI Modal,其中Modal由指令包装.解决方案应遵循以下前提: 该指令声明了字段的转换.这些字段包含在控制器HTML标记中的指令声明中. 控制器中声明的这些字段应显示在模态中. 这些字段的范围应该可以在控制器中访
this plunk的目标是将元素从控制器转换为Angular UI Modal,其中Modal由指令包装.解决方案应遵循以下前提:

>该指令声明了字段的转换.这些字段包含在控制器HTML标记中的指令声明中.
>控制器中声明的这些字段应显示在模态中.
>这些字段的范围应该可以在控制器中访问(请参阅我在控制器中声明了一个应该在Modal中设置值的input1变量).
>我定义了一个内容元素来转换字段.此元素位于模态的模板中.我不确定这个模板何时可以转录它.

总而言之,目标是在控制器HTML标记中声明一组字段并在模态中可用,其中模式包含在指令中,范围在控制器中管理.任何想法将不胜感激.

HTML

<div the-modal control="modalCtl">
    <p>some text</p>
    <input type="text" ng-model="input1" />
</div>

<button type="button" ng-click="open()">Open me!</button>

使用Javascript

var app = angular.module("app",['ui.bootstrap']);

app.controller("ctl",function($scope,$timeout) {

  $scope.modalCtl = {};

  $scope.input1 = "abc";

  $scope.open = function(){
    $scope.modalCtl.openModal();
  };

});


app.directive("theModal",function($uibModal) {
  return {
    restrict: "AE",scope: {              
      control: "="
    },transclude: true,link: function (scope,element,attrs,ctrl,transclude) {
      scope.control = scope.control || {}

      scope.control.openModal = function () {
        scope.instance = $uibModal.open({
          animation: false,scope: scope,template: '<div>in the template</div><div class="content"></div>'
        });
        element.find('.content').append(transclude());
      };
    }
  }
});

解决方法

你已经足够接近实现你的目标,但是,你需要考虑以下几点:

>首先,根据UI Bootstrap docs,$uibModal.open()方法的选项中有一个appendTo属性,默认为body.

If appendTo is not specified,the modal will be appended to the body of your page and becomes a direct child of the body. Therefore querying .content in your directive via element.find('.content') won’t work because it doesn’t exist there.

>其次,AngularJS附带jQLite,jQuery的轻量级版本.这意味着对jQuery的大多数功能的支持有限.其中一种情况是使用.find()方法,该方法仅适用于标记名称.

为了使它与jQuery一起工作(尽管你真的不必因为你仍然可以在链中使用.children()来查询嵌套的DOM元素),你必须在Angular之前加载jQuery(我想你已经).

有关详细信息,请参阅AngularJS docs on angular.element.
>渲染DOM需要花费一点时间用于Angular,因为它需要制作与范围和视图相关的正确绑定,以完成摘要周期等等.
因此,您最终可能会立即查询实际上可能尚未呈现的DOM元素.

The trick to wait for DOM rendering and completion of a digest cycle is to wrap your DOM related code into $timeout wrapper.

考虑到以上几点,自定义指令theModal的link函数中的openModal方法应如下所示:

scope.control.openModal = function () {
    scope.instance = $uibModal.open({
        animation: false,template: '<div>in the template</div><div class="content"></div>',/**
        * Make sure the modal is appended to your directive and NOT `body`
        */
        appendTo: element  
    });


    /**
    * Give Angular some time to render your DOM
    */
    $timeout(function (){
        /**
        * In case jQuery is not available
        */
        // var content = element.children('.modal').children('.modal-dialog').children('.modal-content').children('.content');

        /**
        * Since you have jQuery loaded already
        */
        var content = element.find('.content');

        /**
        * Finally,append the transcluded element to the correct position,* while also making sure that the cloned DOM is bound to the parent scope (i.e. ctl) 
        */
        transclude(scope.$parent,function(clonedContent){
            content.append(clonedContent);
        });
    });
};

请注意transclude函数如何让您控制如何将某些已转换的DOM绑定到自定义作用域而不是默认指令的作用域. plain transclude()调用将把当前可用的scope对象考虑在内 – 即指令的范围 – 用于绑定被转换的DOM.

Demo

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读