patternphpMinor
Notify Property Changed
Viewed 0 times
notifypropertychanged
Problem
Inspired by a SO post, just as an exercise, I tried to implement a way of notifying a consumer of a class about whether a property on an object has changed or not. I'm not attempting to use this in anyway, but I would like to learn from it.
Then, implementing a class;
And finally, usage;
And if you want, you can call
Like I said, I'm not planning on using this, it was an exercise to see if I could do something similar to .NETs INotifyPropertyChanged. And, what better way to get feedback on an idea.
interface INotifyPropertyChanged
{
function PropertyChanged($name);
function RegisterChangeCallback($callback);
}
abstract class NotifyPropertyChanged implements INotifyPropertyChanged
{
public $changes;
public $trackChanges;
private $callback;
public function PropertyChanged($name)
{
if( $this->callback != null){
call_user_func($this->callback, $name);
}
if( !isset($this->changes))
$this->changes = Array();
if( !in_array($name, $this->changes))
$this->changes[] = $name;
}
public function RegisterChangeCallback($callback)
{
$this->callback = $callback;
}
public function __set($name, $value)
{
$previousValue = $this->$name;
$this->$name = $value;
if( $this->trackChanges && $previousValue !== $value) {
$this->PropertyChanged($name);
}
}
public function __get($name)
{
return $this->$name;
}
}Then, implementing a class;
class SampleClass extends NotifyPropertyChanged
{
protected $name;
}And finally, usage;
$class = new SampleClass();
$class->name = "value";
$class->trackChanges = true;
$class->name = "test";
var_dump($class->changes);And if you want, you can call
$class->RegisterChangeCallback(..) to be told when it does change. Like I said, I'm not planning on using this, it was an exercise to see if I could do something similar to .NETs INotifyPropertyChanged. And, what better way to get feedback on an idea.
Solution
First of all it is useless to use
the above code results which also allows you to have all changes
__set or __get if you're trying to access the non existing property that might also cause a cyclic request of the method. Instead you should have an array that contains the values now second thing if you will have the property inside the object the __set or __get methods won't be called. So you should fix those and it should work. If needed I will post a code with the fixcallback != null){
call_user_func($this->callback, $name);
}
if( !isset($this->changes))
$this->changes = Array();
if( !in_array($name, $this->changes))
$this->changes[$name][] = $this->$name;
}
public function RegisterChangeCallback($callback)
{
$this->callback = $callback;
}
public function __set($name, $value)
{
$previousValue = $this->$name;
if( $this->trackChanges && $previousValue !== $value) {
$this->PropertyChanged($name);
}
$this->values[$name] = $value;
}
public function __get($name)
{
if(array_key_exists($name,$this->values)){
return $this->values[$name];
}
return null;
}
}
class SampleClass extends NotifyPropertyChanged
{
}
$class = new SampleClass();
$class->name = "value";
$class->trackChanges = true;
$class->name = "test";
$class->name = "test2";
var_dump($class->changes);the above code results which also allows you to have all changes
array(1) {
["name"]=>
array(2) {
[0]=>
string(5) "value"
[1]=>
string(4) "test"
}
}Code Snippets
<?php
interface INotifyPropertyChanged
{
function PropertyChanged($name);
function RegisterChangeCallback($callback);
}
abstract class NotifyPropertyChanged implements INotifyPropertyChanged
{
public $changes;
public $trackChanges;
private $callback;
protected $values = array();
public function PropertyChanged($name)
{
if( $this->callback != null){
call_user_func($this->callback, $name);
}
if( !isset($this->changes))
$this->changes = Array();
if( !in_array($name, $this->changes))
$this->changes[$name][] = $this->$name;
}
public function RegisterChangeCallback($callback)
{
$this->callback = $callback;
}
public function __set($name, $value)
{
$previousValue = $this->$name;
if( $this->trackChanges && $previousValue !== $value) {
$this->PropertyChanged($name);
}
$this->values[$name] = $value;
}
public function __get($name)
{
if(array_key_exists($name,$this->values)){
return $this->values[$name];
}
return null;
}
}
class SampleClass extends NotifyPropertyChanged
{
}
$class = new SampleClass();
$class->name = "value";
$class->trackChanges = true;
$class->name = "test";
$class->name = "test2";
var_dump($class->changes);array(1) {
["name"]=>
array(2) {
[0]=>
string(5) "value"
[1]=>
string(4) "test"
}
}Context
StackExchange Code Review Q#60052, answer score: 2
Revisions (0)
No revisions yet.