1

以下の場合、いずれかの入力を変更すると、それらすべてが変更されます。私が理解したように、データオブジェクトは3つのスコープすべてに共通であるために発生します

<div class="content-container" ng-app="">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
<div ng-controller="FirstController">
    <input type="text" ng-model="data.message">
    <h1>{{data.message}}</h1>
</div>
<div ng-controller="SecondController">
    <input type="text" ng-model="data.message">
    <h1>{{data.message}}</h1>
</div>

ただし、以下の場合、各スコープには独自のメッセージ オブジェクトがあります。

<div class="content-container" ng-app="">
<input type="text" ng-model="message">
<h1>{{message}}</h1>
<div ng-controller="FirstController">
    <input type="text" ng-model="message">
    <h1>{{message}}</h1>
</div>
<div ng-controller="SecondController">
    <input type="text" ng-model="message">
    <h1>{{message}}</h1>
</div>

なぜAngularはスコープごとに「メッセージ」オブジェクトを作成するのに、スコープごとに「データ」オブジェクトを作成しないのですか? この 2 つの例の主な違いは何ですか?

4

1 に答える 1

2

AngularJS がどのように機能するかではなく、JavaScript が実際にどのように機能するかについてです。次の点を考慮してください。

function Parent() { 
  this.message = ''; 
  this.data    = {};
}
function Child() {}; Child.prototype = new Parent();

ご覧のとおりParent、 をコンストラクタとして使用すると、新しいオブジェクトの 2 つのプロパティが定義されます。最初のものをプリミティブの保存に使用し、2 番目のものをオブジェクトの保存に使用するとします。

Childfunction は非常に単純に定義されています。それ自体のプロパティはなくParent、プロトタイプチェーンにオブジェクトがあります。これで、さらにいくつかのことを行うことができます:

var c = new Child();
c.message      = '42';
c.data.message = '42';
console.log(c.hasOwnProperty('message'));         // true
console.log(c.hasOwnProperty('data'));            // false
console.log(c.data.hasOwnProperty('message'));    // true

違いを見ます?最初のケースでは、 を使用して、オブジェクト ( ) 自体c.messageに新しいプロパティを定義しました。これは、プロトタイプで定義された同じ名前のプロパティをシャドウします。c

ただし、2 番目のケースでは、parentのプロパティを引き続き使用し、その値を新しいプロパティで拡張しています。で新しいプロパティは定義されcず、そのプロトタイプのみが影響を受けます。違いはここでさらに顕著です:

var d = new Child();
d.message      = '34';
d.data.message = '34';

console.log(c.message);      // still '42'
console.log(c.data.message); // now '34'

Angular ディレクティブを使用すると、同様のことが起こります。新しいスコープが定義され、その親スコープからすべての「モデル」プロパティが継承されます。ただし、これらのプロパティが「2 レベル」でない限り、それらに割り当てると、子レベルに同じ名前のプロパティが導入され、親に定義されたプロパティがシャドウされます。

Angular wiki のUnderstanding Scopesドキュメントを学習することをお勧めします。この動作については、より実質的な (そして豊富な図解も!) 説明があります。ただし、この引用はそれをかなりうまく要約しています。

プリミティブに関するこの問題は、常に「.」を使用するという「ベスト プラクティス」に従うことで簡単に回避できます。あなたのngモデルで。

また、実際にプリミティブのみを操作したい場合の回避策がいくつか記載されてい$parent.parentScopePropertyます。最も簡単なものだと思います。

于 2013-09-20T00:33:54.163 に答える