呈现值,无需数据绑定


87

在AngularJS中,如何在不进行2向数据绑定的情况下呈现值?出于性能原因,甚至可能要在给定的时间点渲染值,可能要这样做。

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

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

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

如何在value 没有任何数据绑定的情况下进行渲染?


你的输入和输出是什么?PLZ解释
尼什·库马尔

3
您的示例实际上是单向数据绑定(模型更改->视图更新)。 ng-model为您提供双向数据绑定:模型更改->视图更新,视图更改->模型更新。
Mark Rajcok 2013年

1
更新。抱歉,我的意思是我根本不希望任何数据绑定
Blowsie 2013年

10
我认为这个问题不是可怕的或不应被否决的。实际上,禁用数据绑定以防止不必要的监视实际上是很常见的。
OverZealous 2013年

4
更新:任何阅读本文的人都会发现该视频非常有用。youtube.com/watch?v=zyYpHIOrk_Y
Blowsie 2014年

Answers:


141

角度1.3+

在1.3中,Angular使用以下语法支持此功能。

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

正如在这个答案中提到的。


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/

你们中的某些人可能正在使用有角batarang,并且如注释中所述,如果使用此指令,则该元素在未使用时仍显示为绑定,我很确定这与附加到该元素的类有关。试试这个,它应该可以工作(未经测试)。在评论中让我知道它是否对您有用。

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

@ x0b:如果您具有OCD,并且要删除空class属性,请执行此操作

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

我尚未测试插件,但是我假设AngularJS chrome工具不会像绑定示例那样显示一次绑定元素。有趣的方法是,我将尽快测试这两种方法。
Blowsie


1
毫无疑问,这是因为如果您可以轻松删除ng-binding类
iConnor 2013年

4
这比bindonce插件很棒而且简单得多。我添加了一种在破坏范围之前等待条件的功能,这真的很有帮助。谢谢。
Yaron 2014年

1
@康纳我不同意。例如,我从REST API接收视频对象($ scope.video),并且我想一次性绑定视频标题($ scope.video.title)。即使我在将诺言添加到控制器的作用域中之前就解决了诺言,我仍然必须在DOM上声明一次ng-bind =“ video.title” bind-once。现在,在兑现承诺之前,未定义video.title,并且在定义video.title之前破坏了作用域。我对此的解决方案是将元素包装在某种类型的loading / init标志中,即ng-if =“ someLoadingFlag”,但这是一个糟糕的模式。
SirTophamHatt 2014年

49

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

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

一次性绑定

以::开头的表达式被视为一次性表达式。一次性表达式一旦稳定就将停止重新计算,如果表达式结果为非不确定值,则在第一次摘要后发生(请参见下面的值稳定算法)。


1
这个答案一次又一次。卡尔,我不能称赞你!我强烈建议在有意义的地方积极使用此功能。
XDS

1
哇,我很高兴我向下滚动。我要请康纳在他接受的答案中引用此内容。
JSager 2014年

我有一个包含2000行的表格/列表,并且使用一次性绑定运算符,当我第一次显示/呈现列表时,我的应用程序变得非常慢。太慢了,浏览器问我要停止执行脚本两次还是三遍!
比利G

@ billy-g可以张贴jsfiddle或plunker来说明问题吗?
詹姆斯日报

@James Daily:这是“正常”情况下plnkr.co/edit/rCRP0T5fSgNIllx7F27y,这里是“一次性表达”情况下plnkr.co/edit/Rd5VBVjkcX3sTJYGypUr,但是...我无法在此处复制它。无论如何,“一次性表达式”的运行速度并不快,我必须做更多的调查才能找出它为什么在我的环境中发生的原因(我使用angularjs的1.3 beta 18)
Billy G

20

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

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

该库允许您呈现仅绑定一次的项目-首次初始化时。对这些值的任何进一步更新将被忽略。这是减少页面上手表数量的好方法,因为手表呈现后不会改变。

用法示例:

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

像这样使用时,将在value可用时设置under属性,但随后将禁用手表。


1
我本来要写一个答案“写自己的指令...”,但看来有人已经为我们做到了,很好。
Mark Rajcok 2013年

3
Bindonce非常有用,可以将其作为内置的可选库包括在内$resource
OverZealous 2013年

6
这是我一直在寻找的东西,但是我期望这样的东西可以嵌入角形!
Blowsie 2013年

7

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

与传统的ngRepeat角度:2000s行15s和420mo的RAM(Plunker

使用ngRepeat和@OverZealous的模块:2000行和240mo的RAM需要7s(Plunker

使用ngRepeat和@Connor指令:2000行和500mo RAM(Plunker)为8s

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


1
也会angular-once比较好。谢谢。
alecxe 2014年

@alecxe:我计划在发布稳定版本的AngularJS 1.3时进行测试。
加百利

谢谢,不要忘了包含angular-once软件包(我在此处将其发布为替代选项)。
alecxe 2014年

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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.