【问题标题】:Render value without data-binding在没有数据绑定的情况下呈现值
【发布时间】:2013-09-18 09:05:06
【问题描述】:

在 AngularJS 中,如何在没有 2 路数据绑定的情况下呈现值?出于性能原因,甚至在给定时间点渲染一个值,人们可能想要这样做。

以下示例均使用数据绑定:

<div>{{value}}</div>

<div data-ng-bind="value"></div>

如何在没有任何数据绑定的情况下呈现value

【问题讨论】:

  • 你的输入和输出是什么。请解释
  • 您的示例实际上是单向数据绑定(模型更改-> 视图更新)。 ng-model 为您提供两种数据绑定方式:模型更改 -> 视图更新,视图更改 -> 模型更新。
  • 已更新。抱歉,我的意思是我根本不想要数据绑定
  • 我认为这个问题并不可怕,也不值得一票否决。想要禁用数据绑定以防止不必要的监视实际上很常见。
  • 更新:任何阅读这篇文章的人都可能会发现这个视频非常有用。 youtube.com/watch?v=zyYpHIOrk_Y

标签: javascript angularjs data-binding


【解决方案1】:

Angular 1.3+

在 1.3 中,Angular 使用以下语法支持这一点。

<div>{{::message}}</div>

this answer 中所述。


Angular 1.2 及更低版本

这很简单,不需要插件。看看这个。

这个小指令将轻松完成您想要实现的目标

app.directive('bindOnce', function() {
    return {
        scope: true,
        link: function( $scope ) {
            setTimeout(function() {
                $scope.$destroy();
            }, 0);
        }
    }
});

你可以像这样绑定一次

<div bind-once>I bind once - {{message}}</div>

你可以像平常一样绑定

<div ng-bind="message" bind-once></div>

演示:http://jsfiddle.net/fffnb/

你们中的一些人可能正在使用 angular batarang,并且如 cmets 中所述,如果您使用此指令,则元素仍显示为绑定,但我很确定这与附加到的类有关试试这个元素,它应该可以工作(未测试)。如果它对你有用,请在 cmets 中告诉我。

app.directive('bindOnce', function() {
    return {
        scope: true,
        link: function( $scope, $element ) {
            setTimeout(function() {
                $scope.$destroy();
                $element.removeClass('ng-binding ng-scope');
            }, 0);
        }
    }
});

@x0b: 如果你有强迫症并且你想删除空的class 属性这样做

!$element.attr('class') && $element.removeAttr('class')

【讨论】:

  • 我还没有测试插件,但我认为 AngularJS chrome 工具不会将 bind-once 元素显示为绑定,就像您的示例一样。有趣的方法,我将很快测试这两种方法。
  • 毫无疑问,这是因为如果您可以轻松删除 ng-binding 类
  • 这比 bindonce 插件很棒而且简单得多。我添加了在销毁示波器之前等待条件的功能,这真的很有帮助。谢谢。
  • @Connor 我不同意。例如,我从 REST API 接收视频对象 ($scope.video),我想要一次性绑定视频标题 ($scope.video.title)。即使我在将 promise 添加到控制器的范围之前解决了它,我仍然必须在 DOM 上声明 ng-bind="video.title" bind-once。现在,在 promise 得到解决之前, video.title 是未定义的,并且在 video.title 定义之前范围就被破坏了。我对此的解决方案是将元素包装在某种类型的加载/初始化标志中,ng-if="someLoadingFlag",但这是一个糟糕的模式。
【解决方案2】:

看起来 Angular 1.3(从 beta 10 开始)内置了一次性绑定:

https://docs.angularjs.org/guide/expression#one-time-binding

一次性绑定

以 :: 开头的表达式被视为一次性表达式。 一次性表达式一旦稳定就会停止重新计算, 如果表达式结果是 非未定义值(参见下面的值稳定算法)。

【讨论】:

  • 这个答案一次又一次。卡尔我怎么夸你都不够!我强烈建议在有意义的地方积极使用此功能。
  • 哇,我真的很高兴我向下滚动。我将请康纳在他接受的答案中提及这一点。
  • 我有一个包含 2000 行的表格/列表,并且使用一次性绑定运算符,我的应用程序在第一次显示/呈现列表时变得非常慢。太慢了,浏览器会问我两三遍是否要停止执行脚本!
  • @billy-g 你能发布一个 jsfiddle 或 plunker 来说明这个问题吗?
  • @James Daily:这里是“正常”案例plnkr.co/edit/rCRP0T5fSgNIllx7F27y,这里是“一次性表达”案例plnkr.co/edit/Rd5VBVjkcX3sTJYGypUr 但是......我无法在那里重现它。无论如何,“一次性表达”并没有更快,我必须做更多调查以找出它为什么会在我的环境中发生(我使用 angularjs 的 1.3 beta 18)
【解决方案3】:

使用bindonce module。您需要包含 JS 文件并将其作为依赖项添加到您的应用模块:

var myApp = angular.module("myApp", ['pasvaz.bindonce']);

这个库允许你渲染只绑定一次的项目——当它们第一次初始化时。对这些值的任何进一步更新都将被忽略。对于呈现后不会更改的内容,这是减少页面上观看次数的好方法。

使用示例:

<div bo-text="value"></div>

这样使用时,value下的属性一旦可用就会被设置,但随后手表将被禁用。

【讨论】:

  • 我正要写一个答案“写你自己的指令......”,但看起来有人已经为我们做了这个,很好。
  • Bindonce 非常有用,它可以作为内置可选库包含在内,例如 $resource
  • 这是我一直在寻找的,但是我期待这样的东西可以内置到 Angular 中!
【解决方案4】:

@OverZealous 和@Connor 答案之间的比较:

使用传统的 ngRepeat 的 angular :15s 用于 2000 行和 420mo RAM (Plunker)

使用 ngRepeat 和 @OverZealous 模块:2000 行 7 秒和 240 个月 RAM(Plunker)

使用 ngRepeat 和 @Connor 的指令:2000 行 8 秒和 500 莫 RAM (Plunker)

我使用 Google Chrome 32 进行了测试。

【讨论】:

  • 如果有 angular-once 比较就好了。谢谢。
  • @alecxe :我计划在 AngularJS 1.3 的稳定版本发布后进行测试。
  • 谢谢,不要忘记包含angular-once 包(我已将其作为替代选项发布在这里)。
【解决方案5】:

作为替代方案,还有angular-once 包:

如果你使用 AngularJS,有性能问题,需要显示很多 只读数据,这个项目适合你!

angular-once 实际上是受到bindonce 的启发,并提供了类似的once-* 属性:

<ul>
    <li ng-repeat="user in users">
      <a once-href="user.profileUrl" once-text="user.name"></a>
        <a once-href="user.profileUrl"><img once-src="user.avatarUrl"></a>
        <div once-class="{'formatted': user.description}" once-bind="user.description"></div>
    </li>
</ul>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多