17

angular 2 変更検出メカニズムをテストするための簡単なサンプル プロジェクトを作成しようとしています。メイン インデックス ページのスクリプト タグに純粋な JavaScript オブジェクトを作成します。次のものが含まれます。

        var Tryout = {};
        Tryout.text = "Original text here";
        Tryout.printme = function(){
            console.log(Tryout.text);
        }
        Tryout.changeme = function(){
            Tryout.text = "Change was made";
        }

ログをコンソールに出力する関数と、テキスト プロパティを変更する関数です。

Angular 2 では、コードは次のようになります。

import {Component} from "angular2/core"

@Component({
    selector: 'my-app',
    template: `
        <h1>{{TryoutRef.text}}</h1>
        <input type="text" [(ngModel)]="TryoutRef.text">
        <button (click)="consoleLogMe()">Console Log</button>
        <button (click)="changeMe()">Change me inside</button>
    `
})

export class MyApp{

    TryoutRef:any = Tryout;
    constructor(){
    }
    changeMe(){
        this.TryoutRef.changeme();
    }
    consoleLogMe(){
        console.log(this.TryoutRef.text);
    }

}
declare var Tryout:string;

私がやろうとしているのはこれです: 関数 Tryout.printme() を onclick で通常呼び出すと (完全に角度の外側)、角度が変更を検出して画面を更新するようにします。

私はこの点に成功しました: コンポーネントから Tryout.printme() を呼び出すと (changeme() 関数が Tryout.printme() を呼び出しています)、Angular は変更を検出し、UI を更新しますが、これは問題ありません。また、角度の外から変更し、Angular から consoleLogMe() を呼び出すと、変更されたテキストがログに記録され、UI が更新されます。

Angular が何らかの形で実行されているのと同じ Zone で Tryout.changeme() を実行する必要があると思います。何か案は?私は純粋な javascript/jquery で行われる大きなプロジェクトを持っていますが、モデルに触れずに (まだ) ハンドルバー テンプレートを angular2 コンポーネントにゆっくりと書き直す必要があります。そのためには、モデルを angular と同じゾーンで強制的に実行する必要があります。

Angular 1 でこのようなことをしたい場合は、$scope.$apply でうまくいきます。

例の gif を次に示します。

ここに画像の説明を入力

4

1 に答える 1

11

NgZoneこれを行うには、Angular アプリ内でエクスポートします。通常、Angular 内ですべてのことを行う必要がありますが、本当に Angular の外でロジックを実行したい場合は、zoneあなたが言ったように、正しい を取得する必要があります。

このトリックは、この問題が示すように、Angular の依存性注入を悪用し、注入されたオブジェクトをフックしてzonewindowます。への依存関係を宣言し、エクスポートのために に割り当てます。NgZonewindow.zoneImpl

//our root app component
import {Component, NgZone} from 'angular2/core'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>

    </div>
  `,
})
export class App {
  constructor(zone: NgZone) {
    this.name = 'Angular2'
    window.app = this
    window.zoneImpl = zone
  }
}

zoneImplAngular のブートストラップの後、グローバル変数が必要です。メソッドを使用してrunAngular を開始できます。

zoneImpl.run(() => window.app.name = "new name!")

ライブデモ。

于 2015-12-21T05:43:57.037 に答える