gpt4 book ai didi

angularjs - Angular UI 模态中的嵌入不起作用

转载 作者:行者123 更新时间:2023-12-03 06:52:35 25 4
gpt4 key购买 nike

this plunk的目标是将元素从 Controller 嵌入到 Angular UI Modal 中,其中 Modal 由指令包装。解决方案应遵循以下前提:

  • 该指令声明字段的嵌入。这些字段包含在 Controller HTML 标记的指令声明中。
  • Controller 中声明的这些字段应显示在模态中。
  • 这些字段的范围应该可以在 Controller 中访问(请参阅我在 Controller 中声明了一个 input1 变量,该变量应该在 Modal 中设置一个值)。
  • 我定义了一个 content 元素来嵌入字段。该元素位于模式的模板中。我不确定这个模板什么时候可以嵌入它。

总而言之,目标是在 Controller HTML 标记中声明一组字段并在模态中可用,其中模态被包装在指令中,并且范围在 Controller 中管理。任何想法将不胜感激。

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

最佳答案

您已经足够接近实现嵌入目标,但是,您需要考虑一些事项:

  1. 首先根据UI Bootstrap docs$uibModal.open() 方法的 options 中有一个 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.

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

    要使其像 jQuery 一样工作(尽管您实际上不必这样做,因为您仍然可以在链中使用 .children() 来查询嵌套的 DOM 元素),您必须在 Angular 之前加载 jQuery(我想您已经加载了)。

    引用AngularJS docs on angular.element了解更多信息。

  3. 对于 Angular 来说,渲染 DOM 需要一点时间,因为它需要进行与范围和 View 相关的正确绑定(bind),以完成摘要循环等等。因此,您最终可能会立即查询实际上可能尚未呈现的 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 的链接函数中的 openModal 方法应如下所示:

scope.control.openModal = function () {
scope.instance = $uibModal.open({
animation: false,
scope: scope,
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 绑定(bind)到自定义范围,而不是默认指令的范围。简单的 transclude() 调用将考虑当前可用的范围对象 - 即指令的范围 - 来绑定(bind)嵌入的 DOM。

Demo

关于angularjs - Angular UI 模态中的嵌入不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39734623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com