我正在使用TypeScript自動填充組件(對於Angular 2,雖然這不是問題的核心),並且我希望通過可觀察對象來管理大部分(或全部) RxJs(5.0.0-beta.8)。在通過向上/向下箭頭鍵操作時,我在跟蹤當前項目位置方面存在問題:索引保持卡在0處。使用可觀察事件跟蹤前面列表中的當前位置
以下所有邏輯都被留在單獨的class
中,該接收器接收輸入可觀察值併產生輸出觀察值以訂閱(這就是爲什麼不與Angular 2嚴格相關)。客戶端代碼訂閱正確輸出observables。
下面是一些代碼:
// Component responsible for managing only the list of suggestions
// It receives inputs from text field and it produces outputs
// as current index in list, when to hide list, etc.
class AutocompleteListDriver {
currentIndex$: Observable<number>;
doClose$: Observable<void>;
// ...
constructor(...
matches$: Observable<string[]>, // list of suggestions matching text in field
keyUp$: Observable<KeyboardEvent>, // keyup events from text field
keyDown$: Observable<KeyboardEvent>, // keydown events from text field
...) {
const safeMatches$ = matches$
.startWith([]); // start with a clear, known state internally
// when list is empty, component is hidden at rest:
// detect keys only when component is visible
const isActive$ = safeMatches$
.map(matches => matches.length !== 0);
const activeKeyUp$ = keyUp$
.withLatestFrom(isActive$)
.filter(tuple => tuple[1]) // -> isActive
.map(tuple => tuple[0]); // -> keyboardEvent
this.currentIndex$ = safeMatches$
.switchMap(matches => {
const length = matches.length;
console.log('length: ' + length);
const initialIndex = 0;
const arrowUpIndexChange$ = activeKeyUp$
.filter(isArrowUpKey)
.map(_ => -1);
const arrowDownIndexChange$ = activeKeyUp$
.filter(isArrowDownKey)
.map(_ => +1);
const arrowKeyIndexChange$ = Observable
.merge(arrowUpIndexChange$, arrowDownIndexChange$)
.do(value => console.log('arrow change: ' + value));
const arrowKeyIndex$ = arrowKeyIndexChange$
.scan((acc, change) => {
// always bound result between 0 and length - 1
const index = limitPositive(acc + change, length);
return index;
}, initialIndex)
.do(value => console.log('arrow key index: ' + value))
.startWith(0);
return arrowKeyIndex$;
})
.do(value => console.log('index: ' + value))
.share();
}
}
的想法是,每次的比賽(建議)的新名單發出,在列表當前指數應該開始新的「序列」,可以這麼說。每個序列從0開始,聽取由於向下/向上箭頭鍵的增加/減少,通過小心不超過下限/上限進行累加。
要開始新的序列我將其轉換爲switchMap
。但是,隨着這樣的代碼,控制檯僅示出了:
length: 5
index: 0
和向上箭頭未檢測/向下鍵在所有(試戴arrowDownIndexChange$
插入其它日誌),所以沒有更多的日誌和在最終部件沒有影響。這就好像他們的觀測數據不是已訂閱了,但據我所知switchMap
應該訂閱最新生成的序列並從之前的所有序列中刪除/取消訂閱。
只是嘗試,我用mergeMap
代替:在這種情況下,箭頭鍵被檢測到,但當然問題是所有的序列(由於之前的時刻匹配的情況下)合併在一起,它們的值彼此重疊。除此之外,無論如何,這些匹配列表將不時出現,因此總是存在一個點,即當前索引序列始終保持爲0.該序列與所有其他索引序列合併並重疊,從而導致索引的淨結果停留在0.
我在做什麼錯?
無論如何,你可以把它變成一個plunkr?這將更容易追蹤這個問題。 – paulpdaniels
該組件在其示例應用程序中已啓用[在github上](https://github.com/BrainCrumbz/ng2-autocomplete-words-example/)。 [這是](https://github.com/BrainCrumbz/ng2-autocomplete-words-example/blob/ec42b926f04abea6a722673a7389363196fa36a5/src/client/autocomplete/acw-list-driver.ts#L82)的'開關()'呼叫。我知道這不像一個笨蛋,但也許作爲第一步,可以幫助玩它? – superjos