2013-11-25 5 views
8

Я хотел бы реализовать шаблон наблюдателя в Дарт, но я не уверен, как это сделать.Реализовать шаблон наблюдателя в Dart

Скажем, у меня есть класс:

class MyClass { 

    String observed_field; 

} 

Теперь, когда я изменить поле, я хотел бы напечатать «observed_field изменил» строку в консоль. Довольно просто сделать с помощью пользовательского сеттер:

class MyClass { 

    String _observed_field; 

    get observed_field => _observed_field; 
    set observed_field(v) { 
    _observed_field = v; 
    print("observed_field changed"); 
    } 

} 

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

class MyClass 

    String _observeable_field; 
    String _observeable_field_2; 

    observe(#observeable_field, #observeable_field_2); 

end 

Возможно ли это? Кроме того, было бы супер удивительным, чтобы не иметь те поля, определенные выше observe() вызова, а написать что-то вроде:

observe(String: #_observeable_field, String: #_observeable_field_2); 

Так что эти поля объявляются автоматически.

ответ

8

Вот как это сделать, используя пакет Observe. Пример берется из комментариев кода в этом пакете (и адаптирован к вашему примеру выше). По сути, вы аннотирования поля, которые вы хотите, чтобы можно было наблюдать с @observable аннотацию, а затем прослушивать изменения (которые вы вызываете с вызовом Observable.dirtyCheck();

Во-первых, добавить наблюдаемую пакет в ваш pubspec.yaml

dependencies: 
    observe: any 

Затем быстро создать тестовую программу ...

import 'package:observe/observe.dart'; 

class MyClass extends Object with Observable { 
    @observable String observedField = "Hello"; 

    toString() => observedField.toString(); 
} 

main() { 
    var obj = new MyClass(); 

    // anonymous function that executes when there are changes 
    obj.changes.listen((records) { 
    print('Changes to $obj were: $records'); 
    }); 


    obj.observedField = "Hello World"; 

    // No changes are delivered until we check for them 
    Observable.dirtyCheck(); 

    print('done!'); 
} 

Это производит следующий вывод:

Changes to Hello World were: [#<PropertyChangeRecord Symbol("observedField") from: Hello to: Hello World>] 
done! 

Update в ответ на замечания ... Обновление примера опускает Observable.dirtyCheck() вы можете использовать сеттер и notifyPropertyChanged, с классом вместо смешивания в ChangeNotifier

class MyClass2 extends Object with ChangeNotifier { 

    String _observedField = "Hello"; 

    @reflectable get observedField => _observedField; 
    @reflectable set observedField(v) { 
    _observedField = notifyPropertyChange(#observedField, _observedField, v);  
    } 

    toString() => observedField; 

} 
+0

Я прочитал еще один вопрос о SO и было предложено использовать этот пакет 'Observe'. Однако мне не понравилось, что вам действительно нужно было вызвать 'Observable.dirtyCheck()' для того, чтобы изменения были доставлены. Этот вид отрицает всю точку зрения на что-то, если вам все-таки пришлось, в основном, проверить изменения вручную. – snitko

+1

Если вы посмотрите на пример в документах API, он показывает, как вы можете избежать dirtyCheck(), используя @reflectable annotation и notifyPropertyChange(). Это более похоже на ваш пример. http://api.dartlang.org/docs/channels/stable/latest/observe.html –

+0

Отлично, я благодарю вас. – snitko

Смежные вопросы