Rxjs - 不获取可观察到的 dom 元素的值
Rxjs - Not grabbing the value of dom element in observable
我正在尝试制作一个从输入框中搜索颜色数组的小部件。
在我的 js 文件中的搜索 Observable 中,我引用了输入 dom 元素,我从中获取按键。每当我尝试获取 $input 的值时,我都会变得不确定。但是,当我进入控制台时,我可以 select 元素并获取值。这应该更新值,以便我将受限的按键发送到我的搜索功能。目前,我正在将 undefined 发送回我的 searchColors 函数。
这会抛出一个 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
我认为我的 $input 是此代码中的主要错误。感谢您的帮助!
Javascript
var Observable = Rx.Observable;
var colors = ["AliceBlue",...,"YellowGreen"].map(function (n) {return n.toLowerCase()});
var $input = document.querySelector("#bg-color-input");
var $container = document.querySelector("#bg-color-container");
var $results = document.querySelector("div#ac-list");
var $clear = document.querySelector("#bg-color-clear");
var $node, change;
function setBackground (color) {
this.style.backgroundColor = color;
}
function clearColors () {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
function searchColors (substr) {
colors.forEach(function (color) {
if(color.indexOf(substr.toLowerCase()) > -1) {
var el = document.createElement('div');
el.innerHTML = color;
el.style.backgroundColor = color;
el.className = 'color-node col-md-1'
$results.appendChild(el)
}
})
$node = document.querySelectorAll(".color-node");
change = Observable.fromEvent($node, 'click')
.map(function (e) { return e.target.innerHTML });
change.subscribe(setBackground.bind($container));
}
var search = Observable.fromEvent($input, 'keypress').
throttle(20).
map(function (key) { return $input.value; }).
distinctUntilChanged().
map(function (search) { searchColors(search); });
var clear = Observable.fromEvent($clear, 'click').
map(function (e) { return e })
search.subscribe(searchColors.bind($results))
clear.subscribe(clearColors.bind($results))
HTML
<div class="container">
<div id="bg-color-container">
<h1>Change the Background Color</h1>
<p>
By entering a valid named CSS color you can change the background color of this div.
</p>
<input type="text" id="bg-color-input">
<button id="bg-color-clear">Clear</button>
<div class="row" id="ac-list">
</div>
</div>
这是我的代码的 jsbin
http://jsbin.com/ravagi/edit?html,js,output
你可以使用 RxJs-DOM
包含脚本并更改您的搜索定义,仅此而已。
var search = Rx.DOM.keyup($input)
.pluck('target','value')
.filter( function (text) {
return text.length > 0;
}).debounce(50)
.distinctUntilChanged();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/7.0.3/rx.dom.js"></script>
这是可以通过使用do
运算符或console.log
日志指令来追踪运算符链执行情况的东西。通过这样做,我发现:
你打了两次电话searchColors
。第二次传递的值将始终是未定义的,因为您还没有在 map(function (search) { searchColors(search); });
中返回一个值,所以当您订阅该流时,您会得到 undefined
。也许您出于调试目的在事后添加了该代码?
一旦你更正,你会看到 $input.value
仍然是 undefined
。这里的问题是你对 keypress
做出反应。您应该在 keyup
上做出反应。在 keypress
时间,输入框还没有用您的密钥更新。
简而言之,将适当的行替换为:
var search = Observable.fromEvent($input, 'keyup').
throttle(20).
map(function (key) { return $input.value; }).
distinctUntilChanged();
jsbin : http://jsbin.com/cosetocowe/edit?html,js,output
最后一条评论,在 searchColors
函数中,您追加了新元素,因此在您键入时,您将在末尾添加经过优化的选择。这就是您想要的行为吗?
我正在尝试制作一个从输入框中搜索颜色数组的小部件。
在我的 js 文件中的搜索 Observable 中,我引用了输入 dom 元素,我从中获取按键。每当我尝试获取 $input 的值时,我都会变得不确定。但是,当我进入控制台时,我可以 select 元素并获取值。这应该更新值,以便我将受限的按键发送到我的搜索功能。目前,我正在将 undefined 发送回我的 searchColors 函数。
这会抛出一个 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
我认为我的 $input 是此代码中的主要错误。感谢您的帮助!
Javascript
var Observable = Rx.Observable;
var colors = ["AliceBlue",...,"YellowGreen"].map(function (n) {return n.toLowerCase()});
var $input = document.querySelector("#bg-color-input");
var $container = document.querySelector("#bg-color-container");
var $results = document.querySelector("div#ac-list");
var $clear = document.querySelector("#bg-color-clear");
var $node, change;
function setBackground (color) {
this.style.backgroundColor = color;
}
function clearColors () {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
function searchColors (substr) {
colors.forEach(function (color) {
if(color.indexOf(substr.toLowerCase()) > -1) {
var el = document.createElement('div');
el.innerHTML = color;
el.style.backgroundColor = color;
el.className = 'color-node col-md-1'
$results.appendChild(el)
}
})
$node = document.querySelectorAll(".color-node");
change = Observable.fromEvent($node, 'click')
.map(function (e) { return e.target.innerHTML });
change.subscribe(setBackground.bind($container));
}
var search = Observable.fromEvent($input, 'keypress').
throttle(20).
map(function (key) { return $input.value; }).
distinctUntilChanged().
map(function (search) { searchColors(search); });
var clear = Observable.fromEvent($clear, 'click').
map(function (e) { return e })
search.subscribe(searchColors.bind($results))
clear.subscribe(clearColors.bind($results))
HTML
<div class="container">
<div id="bg-color-container">
<h1>Change the Background Color</h1>
<p>
By entering a valid named CSS color you can change the background color of this div.
</p>
<input type="text" id="bg-color-input">
<button id="bg-color-clear">Clear</button>
<div class="row" id="ac-list">
</div>
</div>
这是我的代码的 jsbin http://jsbin.com/ravagi/edit?html,js,output
你可以使用 RxJs-DOM
包含脚本并更改您的搜索定义,仅此而已。
var search = Rx.DOM.keyup($input)
.pluck('target','value')
.filter( function (text) {
return text.length > 0;
}).debounce(50)
.distinctUntilChanged();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/7.0.3/rx.dom.js"></script>
这是可以通过使用do
运算符或console.log
日志指令来追踪运算符链执行情况的东西。通过这样做,我发现:
你打了两次电话
searchColors
。第二次传递的值将始终是未定义的,因为您还没有在map(function (search) { searchColors(search); });
中返回一个值,所以当您订阅该流时,您会得到undefined
。也许您出于调试目的在事后添加了该代码?一旦你更正,你会看到
$input.value
仍然是undefined
。这里的问题是你对keypress
做出反应。您应该在keyup
上做出反应。在keypress
时间,输入框还没有用您的密钥更新。
简而言之,将适当的行替换为:
var search = Observable.fromEvent($input, 'keyup').
throttle(20).
map(function (key) { return $input.value; }).
distinctUntilChanged();
jsbin : http://jsbin.com/cosetocowe/edit?html,js,output
最后一条评论,在 searchColors
函数中,您追加了新元素,因此在您键入时,您将在末尾添加经过优化的选择。这就是您想要的行为吗?