提问人:akbiggs 提问时间:12/5/2013 更新时间:12/5/2013 访问量:1312
在 Angular 中显示某些内容后立即隐藏某些内容的实用方法是什么?
What is the pragmatic way to immediately hide something after showing it in Angular?
问:
在我用 AngularJS 制作的游戏中,我想显示一些应该立即淡出的文本,以指示角色获得的经验量。我通过向 DOM 添加一个代表体验文本的元素来做到这一点,该元素附加了一个 ngIf 说法,一旦角色杀死怪物就会显示自己。但是,现在我需要立即隐藏文本以触发淡出文本的 ng-leave 动画,并从 DOM 中删除文本,我不确定如何以避免将动画逻辑混合到我的 javascript 中的方式做到这一点。
对于这种情况,有没有一种设计模式可以让我在显示 DOM 后立即隐藏 DOM 中的元素,而不会暴露有关应该播放到我的 JS 代码的动画的详细信息?
答:
这相对简单。你可以通过一个指令和一些 css 来实现这一点。
CSS格式:
myObj {opacity: 1; transition: all 2s}
vanish: {opacity: 0}
HTML格式:
<div my-object>Hello world.</div>
在 Angular 指令的构造函数中:my-object
$elem.addClass('vanish');
我可能完全错了,但我相信在 angular 中显示和隐藏事物的正确方法是使用 ng-hide/show 指令。假设您希望使用此指令,则您的元素应如下所示:
<div class="ng-hide elementClass" ng-hide="scopeBoolean">the text</div>
每当“scopeBoolean”设置为 false 时,这将显示该元素。每当它被设置为“true”时,它都会隐藏元素(ng-show反转了这个逻辑)。这实际上会自动为您添加和删除 ng-hide 类(我在示例中手动添加了它,因此当用户加载页面时,您暂时不会显示它)。
现在,angular 1.2.2 和更新版本真正酷的事情是它们现在支持动画,您可能希望使用它来简化这一点。实际上,只需修改以下 css 即可获得要显示或隐藏元素的过渡。
/* define baseline ng-hide */
.ng-hide { display: none; }
/* ng-hide transitions */
.elementClass.ng-hide-add, .elementClass.ng-hide-remove {
-webkit-transition: 0.5s linear all;
-moz-transition: 0.5s linear all;
-o-transition: 0.5s linear all;
-ms-transition: 0.5s linear all;
transition: 0.5s linear all;
display: block!important;
opacity: 1;
}
.elementClass.ng-hide-add.ng-hide-add-active, .elementClass.ng-hide-remove {
opacity: 0;
}
.elementClass.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
}
所以,angular 的 FAQ 是正确的:“不要再尝试使用 jQuery 来修改控制器中的 DOM。真的。
享受!
评论
这似乎是自定义指令的理想选择,该指令定义了一个“通知区域”,该通知区域侦听(通过$on)从控制器$scope$broadcast的事件。该指令处理 DOM 中消息元素的创建,以及调用 $animate.leave 将其删除。您可以在以下位置查看包含完整代码的示例 plunkr
http://plnkr.co/edit/GMW1W26NNNQiGukDJp1A?p=preview
但是,对于简化的情况,用法是:
<div ng-controller="MainCtrl">
<button ng-click="clicked()">Click me!</button>
<flash-notification></flash-notification>
</div>
然后在控制器中$broadcast消息:
$scope.$broadcast('flashNotification::message','Monster killed (or similar)');
指令的工作原理:它必须在其作用域上侦听这些事件,例如
scope.$on('flashNotification::message', function(e, message) { .... }
然后它可以创建元素,将其注入 flash-notification 元素,然后它可以调用 $animate.leave 在延迟和/或转换后将其删除。有关该部分的详细信息,请参阅上面的 plunkr。
这种模式的好处是它是可重用的指令:您可以在任何控制器的模板中放置一个闪存通知元素,因此您不必通过服务或$rootScope“全局”执行任何操作。由于使用了 $broadcast,只有子作用域才会获得 flashNotification 消息,因此,如果对页面多次使用 flash-notificaiont 指令,则在不处于父/子关系的控制器中,每个都完全隔离。
plunkr 代码处理不好的一件事是快速连续的多个通知。我不确定你想发生什么,所以它只是将它们堆叠起来,并在相同的延迟/过渡后删除每个。
评论