将自己的控制器放置在 ngAnimateSwap 中的指令会导致在每个 'swap' 上初始化新控制器
Directive with it's own controller placed within ngAnimateSwap results in new controller being initialized on every 'swap'
我创建了一个指令 (ParentDir),它有自己的控制器并且其模板绑定到该控制器。它与另一个指令 (Child1) 通信,该指令具有自己的控制器,'requires' 第一个 parent 指令。下面是一个简化的例子:
Module.directive("ParentDir", function () {
return {
templateUrl: '../ParentTemplate',
restrict: 'AEC',
scope: {
},
controllerAs: 'parCtrl',
bindToController: true,
controller: ['$scope', function ($scope) {
parCtrl= this;
parCtrl.title = "PARENT 1 TITLE";
}]}
Module.directive("Child1", function () {
return {
templateUrl: '../Child1Template',
restrict: 'AEC',
require: '^^ParentDir',
scope: {},
controllerAs: 'ch1Ctrl',
bindToController: true,
link: function ($scope, element, attrs, parCtrl) {
$scope.parCtrl= parCtrl;
},
controller: ['$scope', function ($scope) {
ch1Ctrl= this;
ch1Ctrl.title = "CHILD 1 TITLE";
}]}
父目录html:
<child1> </child1>
孩子 1 html:
{{parCtrl.title}}
{{ch1Ctrl.title}}
最后我的 ParentDirective 被初始化成这样:
<div ng-animate-swap="trigger" class="swapclass">
<parent-dir></parent-dir>
</div>
在某些情况下,我需要整个 parent 指令的模板来滑动。我还在其他不需要它的地方使用该指令,我可以按原样使用它。在我确实需要幻灯片动画的情况下,我将它放在 ng-animate-swap 中,如上所示。问题是每次交换触发器更改时,都会初始化一个新的 parCtrl,导致所有内容都被重置!
如何将动画交换与具有隔离作用域和它自己的控制器的指令一起使用,而无需在每次发生交换时都重新初始化控制器?
我们知道,指令是高级标记,它告诉 Angular 的编译器将指定的行为附加到 HTML 元素。当指令放在 DOM 上时,Angular 的 $compile
服务会将指令名称与其代码匹配,对其进行规范化并执行。
但是,ng-animate-swap
会在添加新元素之前从 DOM 中删除 其元素。
这意味着每次交换都会重新编译您的指令,并且每次动画发生时都会创建新的隔离范围。
此问题的解决方案取决于您的应用程序的功能、您的模板有多大以及您需要多久制作一次动画(或动画需要什么):
一个解决方案是在交换动画之外创建另一个指令,该指令包含 parCtrl.title
和 ch1Ctrl.title
(或您拥有的任何其他变量),然后能够将该信息传递给子作用域通过原型继承:
<swap-dir>
<div ng-animate-swap="trigger" class="swapclass">
<parent-dir></parent-dir>
</div>
<swap-dir>
这也可以用控制器完成,也许更容易。您选择做什么将取决于您从何处获取范围变量以及页面上有多少不同元素。
然而,ng-animate-swap
创建了它自己的 作用域,所以虽然我相信这会起作用,但永远有趣的 JavaScript 继承恶作剧可能会导致问题这里也是。
另一种解决方案是完全跳过 ng-animate-swap
并仅使用常规的旧 CSS 过渡动画模板元素,尽管这取决于您在做什么以及您希望它看起来如何。
我创建了一个指令 (ParentDir),它有自己的控制器并且其模板绑定到该控制器。它与另一个指令 (Child1) 通信,该指令具有自己的控制器,'requires' 第一个 parent 指令。下面是一个简化的例子:
Module.directive("ParentDir", function () {
return {
templateUrl: '../ParentTemplate',
restrict: 'AEC',
scope: {
},
controllerAs: 'parCtrl',
bindToController: true,
controller: ['$scope', function ($scope) {
parCtrl= this;
parCtrl.title = "PARENT 1 TITLE";
}]}
Module.directive("Child1", function () {
return {
templateUrl: '../Child1Template',
restrict: 'AEC',
require: '^^ParentDir',
scope: {},
controllerAs: 'ch1Ctrl',
bindToController: true,
link: function ($scope, element, attrs, parCtrl) {
$scope.parCtrl= parCtrl;
},
controller: ['$scope', function ($scope) {
ch1Ctrl= this;
ch1Ctrl.title = "CHILD 1 TITLE";
}]}
父目录html:
<child1> </child1>
孩子 1 html:
{{parCtrl.title}}
{{ch1Ctrl.title}}
最后我的 ParentDirective 被初始化成这样:
<div ng-animate-swap="trigger" class="swapclass">
<parent-dir></parent-dir>
</div>
在某些情况下,我需要整个 parent 指令的模板来滑动。我还在其他不需要它的地方使用该指令,我可以按原样使用它。在我确实需要幻灯片动画的情况下,我将它放在 ng-animate-swap 中,如上所示。问题是每次交换触发器更改时,都会初始化一个新的 parCtrl,导致所有内容都被重置!
如何将动画交换与具有隔离作用域和它自己的控制器的指令一起使用,而无需在每次发生交换时都重新初始化控制器?
我们知道,指令是高级标记,它告诉 Angular 的编译器将指定的行为附加到 HTML 元素。当指令放在 DOM 上时,Angular 的 $compile
服务会将指令名称与其代码匹配,对其进行规范化并执行。
但是,ng-animate-swap
会在添加新元素之前从 DOM 中删除 其元素。
这意味着每次交换都会重新编译您的指令,并且每次动画发生时都会创建新的隔离范围。
此问题的解决方案取决于您的应用程序的功能、您的模板有多大以及您需要多久制作一次动画(或动画需要什么):
一个解决方案是在交换动画之外创建另一个指令,该指令包含 parCtrl.title
和 ch1Ctrl.title
(或您拥有的任何其他变量),然后能够将该信息传递给子作用域通过原型继承:
<swap-dir>
<div ng-animate-swap="trigger" class="swapclass">
<parent-dir></parent-dir>
</div>
<swap-dir>
这也可以用控制器完成,也许更容易。您选择做什么将取决于您从何处获取范围变量以及页面上有多少不同元素。
然而,ng-animate-swap
创建了它自己的 作用域,所以虽然我相信这会起作用,但永远有趣的 JavaScript 继承恶作剧可能会导致问题这里也是。
另一种解决方案是完全跳过 ng-animate-swap
并仅使用常规的旧 CSS 过渡动画模板元素,尽管这取决于您在做什么以及您希望它看起来如何。