麻烦运行一个观察者模式的例子
Trouble running an Observer Pattern example
我正在尝试重现 Learning JavaScript Design Patterns 书中给出的观察者模式示例,但我在 extend
函数中遇到此错误:
我正在使用本书中从这一行以下开始的代码:
First, let's model the list of dependent Observers a subject may have:
我已经在 fiddle 中设置了代码,我想了解为什么会出现错误。
您问题中报告的错误的问题是 extend()
的第一个参数不是有效对象。
当我 运行 你的 jsFiddle 时,它报告说 Observer is not defined
。
如果 Observer()
模式应该与 Subject()
模式平行,那么您缺少这段代码:
function Observer() {
this.observers = new ObserverList();
}
或者,也许您只需要更改:
extend( new Observer(), check );
至:
extend( new ObserverList(), check );
以便它使用您为 ObserverList()
显示的代码。
事实上,当我在你的 jsFiddle 中按下按钮时,发生的错误是 Uncaught ReferenceError: Observer is not defined
,这进一步证实了上述情况。
而且,当我应用该更改时,代码似乎 运行 此处:http://jsfiddle.net/jfriend00/8xmu1mcg/,虽然我不确切知道它应该做什么,但它添加了一个复选框并在那里没有错误。
唯一的问题是您忽略了定义 Observer
。添加函数定义后,fiddle 有效:
http://jsfiddle.net/cm5a62jb/1/
// The Observer
function Observer(){
this.update = function(){
// ...
};
}
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.add = function( obj ){
return this.observerList.push( obj );
};
ObserverList.prototype.count = function(){
return this.observerList.length;
};
ObserverList.prototype.get = function( index ){
if( index > -1 && index < this.observerList.length ){
return this.observerList[ index ];
}
};
ObserverList.prototype.indexOf = function( obj, startIndex ){
var i = startIndex;
while( i < this.observerList.length ){
if( this.observerList[i] === obj ){
return i;
}
i++;
}
return -1;
};
ObserverList.prototype.removeAt = function( index ){
this.observerList.splice( index, 1 );
};
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function( observer ){
this.observers.add( observer );
};
Subject.prototype.removeObserver = function( observer ){
this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
};
Subject.prototype.notify = function( context ){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update( context );
}
};
// Extend an object with an extension
function extend( extension, obj ){
for ( var key in extension ){
obj[key] = extension[key];
}
}
// References to our DOM elements
var controlCheckbox = document.getElementById( "mainCheckbox" ),
addBtn = document.getElementById( "addNewObserver" ),
container = document.getElementById( "observersContainer" );
// Concrete Subject
// Extend the controlling checkbox with the Subject class
extend( new Subject(), controlCheckbox );
// Clicking the checkbox will trigger notifications to its observers
controlCheckbox.onclick = function(){
controlCheckbox.notify( controlCheckbox.checked );
};
addBtn.onclick = addNewObserver;
// Concrete Observer
function addNewObserver(){
// Create a new checkbox to be added
var check = document.createElement( "input" );
check.type = "checkbox";
// Extend the checkbox with the Observer class
extend( new Observer(), check );
// Override with custom update behaviour
check.update = function( value ){
this.checked = value;
};
// Add the new observer to our list of observers
// for our main subject
controlCheckbox.addObserver( check );
// Append the item to the container
container.appendChild( check );
}
<button id="addNewObserver">Add New Observer checkbox</button>
<input id="mainCheckbox" type="checkbox"/>
<div id="observersContainer"></div>
我正在尝试重现 Learning JavaScript Design Patterns 书中给出的观察者模式示例,但我在 extend
函数中遇到此错误:
我正在使用本书中从这一行以下开始的代码:
First, let's model the list of dependent Observers a subject may have:
我已经在 fiddle 中设置了代码,我想了解为什么会出现错误。
您问题中报告的错误的问题是 extend()
的第一个参数不是有效对象。
当我 运行 你的 jsFiddle 时,它报告说 Observer is not defined
。
如果 Observer()
模式应该与 Subject()
模式平行,那么您缺少这段代码:
function Observer() {
this.observers = new ObserverList();
}
或者,也许您只需要更改:
extend( new Observer(), check );
至:
extend( new ObserverList(), check );
以便它使用您为 ObserverList()
显示的代码。
事实上,当我在你的 jsFiddle 中按下按钮时,发生的错误是 Uncaught ReferenceError: Observer is not defined
,这进一步证实了上述情况。
而且,当我应用该更改时,代码似乎 运行 此处:http://jsfiddle.net/jfriend00/8xmu1mcg/,虽然我不确切知道它应该做什么,但它添加了一个复选框并在那里没有错误。
唯一的问题是您忽略了定义 Observer
。添加函数定义后,fiddle 有效:
http://jsfiddle.net/cm5a62jb/1/
// The Observer
function Observer(){
this.update = function(){
// ...
};
}
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.add = function( obj ){
return this.observerList.push( obj );
};
ObserverList.prototype.count = function(){
return this.observerList.length;
};
ObserverList.prototype.get = function( index ){
if( index > -1 && index < this.observerList.length ){
return this.observerList[ index ];
}
};
ObserverList.prototype.indexOf = function( obj, startIndex ){
var i = startIndex;
while( i < this.observerList.length ){
if( this.observerList[i] === obj ){
return i;
}
i++;
}
return -1;
};
ObserverList.prototype.removeAt = function( index ){
this.observerList.splice( index, 1 );
};
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function( observer ){
this.observers.add( observer );
};
Subject.prototype.removeObserver = function( observer ){
this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
};
Subject.prototype.notify = function( context ){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update( context );
}
};
// Extend an object with an extension
function extend( extension, obj ){
for ( var key in extension ){
obj[key] = extension[key];
}
}
// References to our DOM elements
var controlCheckbox = document.getElementById( "mainCheckbox" ),
addBtn = document.getElementById( "addNewObserver" ),
container = document.getElementById( "observersContainer" );
// Concrete Subject
// Extend the controlling checkbox with the Subject class
extend( new Subject(), controlCheckbox );
// Clicking the checkbox will trigger notifications to its observers
controlCheckbox.onclick = function(){
controlCheckbox.notify( controlCheckbox.checked );
};
addBtn.onclick = addNewObserver;
// Concrete Observer
function addNewObserver(){
// Create a new checkbox to be added
var check = document.createElement( "input" );
check.type = "checkbox";
// Extend the checkbox with the Observer class
extend( new Observer(), check );
// Override with custom update behaviour
check.update = function( value ){
this.checked = value;
};
// Add the new observer to our list of observers
// for our main subject
controlCheckbox.addObserver( check );
// Append the item to the container
container.appendChild( check );
}
<button id="addNewObserver">Add New Observer checkbox</button>
<input id="mainCheckbox" type="checkbox"/>
<div id="observersContainer"></div>