データバインディングなしで値をレンダリングする


87

AngularJSでは、双方向データバインディングなしで値をどのようにレンダリングできますか?パフォーマンス上の理由から、または特定の時点で値をレンダリングするために、これを行うことができます。

次の例では、どちらもデータバインディングを使用しています。

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

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

データバインディングvalue なしでどのようにレンダリングしますか?


whatsあなたの入力と出力。plzの説明
Nitish Kumar

3
実際の例は、一方向のデータバインディングです(モデルの変更->ビューの更新)。 ng-model双方向のデータバインディングが提供されます。モデルの変更->更新の表示、変更の表示->モデルの更新。
Mark Rajcok 2013

1
更新しました。申し訳ありませんが、データバインドはまったく必要ありません
Blowsie

10
この質問はひどいものではなく、反対票に値するとは思いません。不要な監視を防ぐためにデータバインディングを無効にするのが実際に一般的です。
OverZealous 2013

4
更新:この記事を読んでいる人なら誰でも、おそらくこのビデオが非常に役立つことに気付くでしょう。youtube.com/watch?v=zyYpHIOrk_Y
Blowsie 2014年

回答:


141

Angular 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/

あなたの一部は角度のあるバタランを使用している可能性があり、コメントで述べたように、このディレクティブを使用する場合、要素がまだバインドされていない場合でも要素としてバインドとして表示されます。これを試してください、それはうまくいくはずです (テストされていません)。うまくいったかどうかコメントで教えてください。

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')

imはまだプラグインをテストしていませんが、AngularJS chromeツールはbind-once要素をバインディングとして表示しないと思います。興味深いアプローチですが、両方のアプローチをすぐにテストします。
ブロージー2013

これを参照してください-それは、バインディングの両方を示してdl.dropboxusercontent.com/u/14037764/Development/stackoverflow/...
Blowsie

1
間違いなくそれは、簡単に削除できるng-bindingクラスの場合
iConnor

4
これは、bindonceプラグインよりも優れており、はるかに単純です。スコープを破棄する前に条件を待機する機能を追加しました。これは非常に役立ちます。ありがとう。
Yaron

1
@Connor同意しない。たとえば、REST APIからビデオオブジェクト($ scope.video)を受け取っており、ビデオタイトル($ scope.video.title)の1回限りのバインディングが必要です。コントローラのスコープに追加する前にプロミスを解決したとしても、DOMでng-bind = "video.title" bind-onceを宣言する必要があります。これで、promiseが解決される前に、video.titleは未定義になり、スコープはvideo.titleが定義される前に破棄されます。これに対する私が持っている解決策は、要素を何らかのタイプのロード/初期化フラグng-if = "someLoadingFlag"でラップすることですが、それは不十分なパターンです。
SirTophamHatt 2014

49

Angular 1.3(ベータ10以降)にはワンタイムバインディングが組み込まれているようです。

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

ワンタイムバインディング

::で始まる式は、1回限りの式と見なされます。1回限りの式は、安定すると再計算を停止します。これは、式の結果が未定義の値でない場合、最初のダイジェストの後に発生します(以下の値安定化アルゴリズムを参照)。


1
この答えは何度も。私はあなたを十分に賞賛することができません!この機能を積極的に使用することを強くお勧めします。
XDS 14

1
うわー、スクロールダウンして本当に嬉しいです。私はコナーに彼の受け入れられた答えでこれを参照するように頼むつもりです。
JSager 2014

2000行のテーブル/リストがあり、ワンタイムバインディング演算子を使用すると、最初にリストを表示/レンダリングするときにアプリが非常に遅くなります。非常に遅いため、スクリプトの実行を停止するかどうかブラウザから2〜3回尋ねられます。
ビリーG

@ billy-g問題を説明するjsfiddleまたはplunkerを投稿できますか?
James Daily、

@James Daily:「通常の」ケースplnkr.co/edit/rCRP0T5fSgNIllx7F27yと、ここに「1回限りの式」のケースplnkr.co/edit/Rd5VBVjkcX3sTJYGypUrがありますが、ここでは再現できません。とにかく、「1回限りの式」の方が高速ではないため、自分の環境で発生する理由を見つけるためにさらに調査する必要があります(私はangularjsの1.3ベータ18を使用しています)
Billy G

20

bindonceモジュールを使用します。JSファイルをインクルードし、それを依存関係としてアプリモジュールに追加する必要があります。

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

このライブラリを使用すると、最初に初期化されたときに一度だけバインドされたアイテムをレンダリングできます。これらの値をさらに更新しても無視されます。これは、レンダリング後に変更されないものについて、ページ上のウォッチの数を減らすための優れた方法です。

使用例:

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

このように使用した場合、使用可能なプロパティvalueが設定されますが、時計は無効になります。


1
「独自のディレクティブを記述してください...」という回答を書こうとしていましたが、誰かがすでに私たちのためにそれを行っているようです。
Mark Rajcok、2013

3
Bindonceは、などの組み込みのオプションライブラリとして含めることができるほど十分に便利です$resource
OverZealous 2013

6
これは私が探していたものですが、このようなものが角度に組み込まれることを期待していました!
ブロージー2013

7

@OverZealousと@Connorの回答の比較:

角度のある従来のngRepeatを使用すると、2000行で15秒、RAMが420moPlunker

ngRepeatと@OverZealousのモジュールを使用する場合:2000行で7秒、240moのRAM(Plunker

ngRepeatと@Connorのディレクティブを使用する場合:2000行で8秒、500moのRAM(Plunker

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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.