Заполнение производных полей в компоненте Angular Dart

У меня есть компонент, который принимает один атрибут. Я хочу заполнить поле в компоненте значением, полученным из этого атрибута. Я столкнулся с проблемой, что привязка с атрибутом не произошла, когда код внутри конструктора запускается. Как же тогда установить значение производного поля?

Вот код:

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);
}

person Shailen Tuli    schedule 12.01.2014    source источник


Ответы (2)


Одним из возможных решений является реализация компонента 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);
}
person Shailen Tuli    schedule 12.01.2014

Текущая передовая практика для производных полей состоит в том, чтобы вычислять их по запросу и кэшировать результаты. Ожидая, приложение может избежать ненужной работы, когда производное поле не используется.

например ваш пример компонента будет выглядеть так:

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 для проверки изменений, наш компонент должен возвращать идентичный список токенов, если компонент не изменился.

person James deBoer    schedule 12.01.2014