3

単一の属性を取るコンポーネントがあります。コンポーネントのフィールドに、この属性から派生した値を入力したいと考えています。コンストラクター内のコードが実行されたときに、属性とのバインディングが行われていないという問題が発生しています。では、派生フィールドの値を設定するにはどうすればよいでしょうか。

ここにいくつかのコードがあります:

import 'package:angular/angular.dart';

@NgComponent(
    selector: 'tokens',
    templateUrl: './component.html',
    cssUrl: './component.css',
    publishAs: 'ctrl',
    map: const {
      'text' : '@text'
    }
)
class TokensComponent {
  String text;

  // Derived field.
  List<Token> tokens = new List<Token>();

  TokensComponent() {
    print('inside constructor, text = $text'); // $text is null.
  }

}

class Token {
  String char;
  bool important;
  Token(this.char, this.important);
}
4

2 に答える 2

3

考えられる解決策の 1 つは、コンポーネントを実装してメソッドNgAttachAwareを定義するattach()ことです。派生フィールドの値は、内部で設定できattach()ます。これを行うためのより慣用的な方法があるかどうかはわかりませんが、使用するとうまくいくattach()ようです。

コードは次のとおりです。

import 'package:angular/angular.dart';

@NgComponent(
    selector: 'tokens',
    templateUrl: './component.html',
    cssUrl: './component.css',
    publishAs: 'ctrl',
    map: const {
      'text' : '@text'
    }
)
class TokensComponent implements NgAttachAware {
  String text;

  // Derived field.
  List<Token> tokens = new List<Token>();

  TokensComponent() {
    print('inside constructor, text = $text');
  }

  void attach() {
    print('inside attach(), text = $text'); // $text is no longer null.
    text.split('').forEach((char) => tokens.add(new Token(char, false)));
  }
}

class Token {
  String char;
  bool important;
  Token(this.char, this.important);
}
于 2014-01-12T22:01:06.803 に答える
3

派生フィールドの現在のベスト プラクティスは、オンデマンドで計算し、結果をキャッシュすることです。待機することで、派生フィールドが使用されていないときにアプリが不要な作業を回避できる場合があります。

たとえば、コンポーネントの例は次のようになります。

import 'package:angular/angular.dart';

@NgComponent(
    selector: 'tokens',
    templateUrl: './component.html',
    cssUrl: './component.css',
    publishAs: 'ctrl',
    map: const {
      'text' : '@text'
    }
)
class TokensComponent {
  Map<bool, List<Token>> _tokensCache = new Map<bool, List<Token>>();

  String _text;
  get text => _text;
  set text(t) {
    _text = t;
    _tokensCache.clear();  // invalidate the cache any time text changes.
  }

  // Derived field.
  List<Token> get tokens =>
    text == null ? [] : _tokensCache.putIfAbsent(true,
        () => text.split('').map((char) =>  new Token(char, false)));

}

現在、トークンは常に最新であり、何もトークンを要求しない場合、コンポーネントはそのフィールドを計算しません。

この例では、キャッシュが必要です。Angular のダーティ チェックはidentical変更のチェックに使用されるため、コンポーネントが変更されていない場合、コンポーネントは同一のトークン リストを返す必要があります。

于 2014-01-12T23:22:59.643 に答える