2013-01-17 24 views
7

The view is not updated in AngularJSのようなこの問題に関するスレッドを読んでいますが、私の単純な例にそれを適用する方法はまだ分かりません。モデルがAngularJSで更新されたときにビューが更新されない

私はこの機能を持っている:myModelはコード内の他の場所で更新されたときに

function MyPageView($scope) { 
    var myModel = new MyModel(); 
    $scope.myModel = myModel; 
} 

(ときにユーザーがクリックし、相互作用、XHRリクエストを送信する)、それは私のビューを更新しません。私は$ applyで何かする必要があることを理解していますが、どこでどのように理解できませんでした。

この単純なユースケースでこの問題を解決するにはどうすればよいですか?

(それが問題のために必要であれば)私のモデルは次のようになります - それは、それの内部にAngularJSコードを持っていない:

JSfiddle例追加
var MyModel = function() { 
    var _this = this; 
    ... 
    _this.load = function(){...}; 
    _this.updateModel = function(){...}; 
    ... 
    return _this; 
} 

http://jsfiddle.net/DAk8r/2/

+1

何が間違っているかを正確に伝えるための十分なコードはありません。モデルの更新を引き起こしているが、ビューを更新していないインタラクションの例を教えてください。 jsFiddleやそれに類するものの実例があれば、それはさらに優れています。 –

+0

あなたがビューコードから抜粋を投稿し、コントローラとのやりとりの仕方やmyModelが期待される場所を示すことができたら、それは素晴らしいことでしょう。また、MyModel関数をいくらか肉体化することができれば役に立ちます。 Brandonが上で述べたように、そこにあるものは何が起こっているのかをテレビで見るのに本当に十分ではありません。 –

+0

@BrandonTilley、私はJSfiddleの例を追加しました:http://jsfiddle.net/DAk8r/1/ – Alon

答えて

9

問題の核心は「、あなたは非常に伝統的でAngularJSをミックスしようとしているということですjQuery-スープスタイル "のJavaScriptパターン。 Angularでは、DOM操作とインタラクション(クリックを含む)を行うために常にディレクティブを使用する必要があります。この場合、あなたのコードはより以下のようになります。

<div ng-controller="myModelCtrl"> 
    <div>Number is {{myModel.number}}</div> 
    <a ng-click="myModel.updateNumber()">Update Number</a> 
</div> 
function myModelCtrl($scope) { 
    var myModel = new MyModel(); 
    $scope.myModel = myModel; 
} 

function MyModel() { 
    var _this = this; 

    _this.number = 0; 

    _this.updateNumber = function() { 
    _this.number += 1; 
    alert('new number should display ' + _this.number); 
    } 

    return _this; 
} 

お知らせ代わりにjQueryを使って手動clickハンドラを設定する、私たちはどのように使用するか、角度の内蔵でng-clickディレクティブ。これにより、Angularスコープのライフサイクルに縛られ、ユーザーがリンクをクリックしたときにビューが正しく更新されます。

ここにはAngularJS FAQの引用があります。私はあなたが習慣を壊すのを助けるかもしれない部分を大胆にしました。

陥りやすい落とし穴

角度サポートチャネル(Freenodeの上#angularjs)は角度の新規ユーザーは、に陥る落とし穴を繰り返しの数を見ています。このドキュメントは、あなたがそれらを難しい方法で発見する前にそれらを指摘することを目指しています。コントローラでDOMを変更するjQueryのを使用しようとして

DOM操作

ストップ。本当に。これには、要素の追加、要素の削除、内容の取得、表示および非表示が含まれます。組み込みのディレクティブを使用するか、必要に応じて独自のディレクティブを作成して、DOM操作を行います。機能の複製については、以下を参照してください。

習慣を壊すのに苦労している場合は、アプリからjQueryを削除することを検討してください。本当に。 Angularには$ httpサービスと強力な指示があり、ほとんどの場合それが不要です。 AngularのバンドルされたjQLiteには、Angularディレクティブ、特にイベントへのバインディングの作成に最も一般的に使用される機能がいくつかあります。

最後に、ここにあなたの例では、この技術使用して作業:アンギュラアプリでhttp://jsfiddle.net/BinaryMuse/xFULR/1/

+0

なぜあなたは 'var _this = this;'を必要としますか? – Alex78191

9

試して$ scope(モデルの更新後のコントローラ内の$ apply())

+1

私のコントローラの中では、$ scopeはjsfiddle.net/DAk8r/2に見られるように曖昧さがありません。 – Alon

+0

これは素晴らしい動作です。しかし、それがなぜ必要なのか説明してください。これはデフォルトで角度の約束[双方向データバインディング](https://docs.angularjs.org/tutorial/step_04) – Sami

1

http://jsfiddle.net/zCC2c/

あなたの問題は二重です。

1)DOMElements(クリックハンドラー内で$によって返されたaなど)がデフォルトを防ぎません。jsfiddleに構文エラーがあります。実際にイベントを渡す必要がありました(軽微な構文の問題)。そのように、コントローラの範囲内で、あなたの変数定義を置くことによって

2):

function MyCtrl($scope){ 
    $scope.foo = foo; 
} 

あなたはそれは、クラスのインスタンスごとに一度実行します確認してください。何をしたい

は次のとおりです。

function MyCtrl($scope){ 
     $scope.someAngularClickHandler=function(){ 
     $scope.foo = foo; 
     } 
} 

そして、もっと徹底的codesampleのために、あなたのリンクに

<a href="foo" id="bar" ng-click="someAngularClickHandler()"> 

はリンクjsfiddleを参照してください。

理論の良い概要は、ここで最初の話で見つけることができます:

http://www.youtube.com/watch?feature=player_embedded&v=VxuN6WO3tIA

+2

コントローラはシングルトンではありません。 MyCtrlは同じページで複数回インスタンス化できます。多分あなたはコントローラーと混乱しているサービスをしているかもしれません。サービスはシングルトンです。 –

0

を、モデルが 通常 が時々いない独立したJavaScriptオブジェクトとして、$の範囲に実装されています。

<div ng-controller="myModelCtrl"> 
    <div>Number is {{number}}</div> 
    <a ng-click="updateNumber()">Update Number</a> 
</div> 

ここにはjQueryを使って、fiddleだし、それがためにフィドルを設定するための「通常の方法」を示しています。ここにあなたのアプリケーションの書き換えが

function myModelCtrl($scope) { 
    $scope.number = 0; 
    $scope.updateNumber = function() { 
    $scope.number += 1; 
    alert('new number should display ' + $scope.number); 
    } 
} 

HTMLのことを行う方法を示しています角度。

+2

AngularJSのベストプラクティスはしばしば引用されています[スコープはあなたのモデルではありません。スコープはあなたのモデルを取り付けるものです]](http://youtu.be/ZhfUv0spHCY?t=30m)非常に単純なコントローラの場合、物事は大丈夫かもしれませんが、通常は独自のモデルレイヤーが必要です。 –

+0

@Brandon、ビデオリンクのおかげで(私はまだそれを見たことがなかった)。私は今、この文を[スコープ](http://docs.angularjs。org/guide/scope)ページ: "スコープは、アプリケーションモデルを参照するオブジェクトです。"モデルレイヤーを定義する方法としてサービスがありますか?そうでない場合は、モデルを定義する場所はどこですか?別のモデルレイヤーを持つ角型アプリケーションの良い例を知っていますか? –

+1

他の読者のためのFYI、Brandonとの他のコメント交換では、サービスはモデルを定義する場所であると言います。たとえば、Brandonの[この回答](http://stackoverflow.com/a/14667066/215945)を参照してください。 –

関連する問題