2016-03-28 99 views
0

只是試圖來愚蠢的東西,並與Cycle.js玩耍。並遇到問題。基本上我只是有一個按鈕。當你點擊它時,假設將該位置導航到隨機哈希並顯示它。幾乎就像一個沒有預定義路由的愚蠢路由器。 IE瀏覽器。路線是動態的。再次,這不是什麼實際的,我只是搞亂了一些東西,並試圖學習Cycle.js。但是當我點擊「添加」按鈕後,下面的代碼崩潰了。但是位置已更新。如果我實際上只是導航到「#/ asdf」,它顯示正確的內容與「哈希:#/ asdf」。不知道爲什麼流與錯誤而崩潰:簡單的歷史記錄推碰

渲染dom.js:242類型錯誤:無法讀取屬性未定義「訂閱」(...)

import Rx from 'rx'; 
import Cycle from '@cycle/core'; 
import { div, p, button, makeDOMDriver } from '@cycle/dom'; 
import { createHashHistory } from 'history'; 
import ranomdstring from 'randomstring'; 

const history = createHashHistory({ queryKey: false }); 

function CreateButton({ DOM }) { 
    const create$ = DOM.select('.create-button').events('click') 
    .map(() => { 
     return ranomdstring.generate(10); 
    }).startWith(null); 

    const vtree$ = create$.map(rs => rs ? 
    history.push(`/${rs}`) : 
    button('.create-button .btn .btn-default', 'Add') 
); 

    return { DOM: vtree$ }; 
} 

function main(sources) { 
    const hash = location.hash; 
    const DOM = sources.DOM; 

    const vtree$ = hash ? 
    Rx.Observable.of(
     div([ 
     p(`Hash: ${hash}`) 
     ]) 
    ) : 
    CreateButton({ DOM }).DOM; 

    return { 
    DOM: vtree$ 
    }; 
} 

Cycle.run(main, { 
    DOM: makeDOMDriver('#main-container') 
}); 

感謝您的幫助

回答

2

在你的函數CreateButton你映射你的點擊,history.push(),而不是它映射到vtree這將導致錯誤

function CreateButton({ DOM }) { 
    ... 
    const vtree$ = create$.map(rs => rs 
    ? history.push(`/${rs}`) // <-- not a vtree 
    : button('.create-button .btn .btn-default', 'Add') 
); 
    ... 
} 

相反,你可以用做運營商執行hashchange:在函數式編程

function CreateButton({ DOM }) { 
    const create$ = 
    ... 
    .do(history.push(`/${rs}`)); // <-- here 

    const vtree$ = Observable.of(
    button('.create-button .btn .btn-default', 'Add') 
); 
    ... 
} 

但是你不應該在你的應用程序邏輯執行副作用,每一個功能必須保持pure。相反,所有的副作用都應該由司機處理。要了解更多,請查看drivers section on Cycle's documentation

在消息結尾處看到正在工作的驅動程序跳轉。


而且您main功能你不使用流渲染你vtree。由於vtree$ = hash ? ... : ...僅在應用程序引導時評估過一次(當主函數被評估並「將每個流連接在一起」時),所以它不會反應到locationHash更改。

的改善將是宣佈你main的vtree $如下,同時保持相同的邏輯:

const vtree$ = hash$.map((hash) => hash ? ... : ...) 

這裏是一個小locationHash驅動器的完整解決方案:

import Rx from 'rx'; 
import Cycle from '@cycle/core'; 
import { div, p, button, makeDOMDriver } from '@cycle/dom'; 
import { createHashHistory } from 'history'; 
import randomstring from 'randomstring'; 


function makeLocationHashDriver (params) { 
    const history = createHashHistory(params); 

    return (routeChange$) => { 
    routeChange$ 
     .filter(hash => { 
     const currentHash = location.hash.replace(/^#?\//g, '') 
     return hash && hash !== currentHash 
     }) 
     .subscribe(hash => history.push(`/${hash}`)); 

    return Rx.Observable.fromEvent(window, 'hashchange') 
     .startWith({}) 
     .map(_ => location.hash); 
    } 
} 

function CreateButton({ DOM }) { 
    const create$ = DOM.select('.create-button').events('click') 
    .map(() => randomstring.generate(10)) 
    .startWith(null); 

    const vtree$ = Rx.Observable.of(
    button('.create-button .btn .btn-default', 'Add') 
); 

    return { DOM: vtree$, routeChange$: create$ }; 
} 

function main({ DOM, hash }) { 
    const button = CreateButton({ DOM }) 
    const vtree$ = hash.map(hash => hash 
    ? Rx.Observable.of(
     div([ 
      p(`Hash: ${hash}`) 
     ]) 
    ) 
    : button.DOM 
) 

    return { 
    DOM: vtree$, 
    hash: button.routeChange$ 
    }; 
} 

Cycle.run(main, { 
    DOM: makeDOMDriver('#main-container'), 
    hash: makeLocationHashDriver({ queryKey: false }) 
}); 

PS:您的randomstring函數名稱存在拼寫錯誤,我在示例中對其進行了修復。

+0

啊是有道理的。應該已經想通了。謝謝幫助表示讚賞 – Bojan

5

我會進一步建議使用@週期/歷史做你的路徑切換 (只顯示相關部分)

import {makeHistoryDriver} from '@cycle/history' 
import {createHashHistory} from 'history' 

function main(sources) { 
    ... 
    return {history: Rx.Observable.just('/some/route') } // a stream of urls 
} 

const history = createHashHistory({ queryKey: false }) 
Cycle.run(main, { 
    DOM: makeDOMDriver('#main-container'), 
    history: makeHistoryDriver(history), 
}) 
+0

你好,感謝您的反饋。對不起,我覺得真的很愚蠢,但我無法使用@ cycle/history;我嘗試了不同的東西並閱讀文檔。如何將歷史驅動程序與按鈕的更改事件連接起來?我想結合這兩個流? – Bojan

+0

嗯,我想我終於明白了,謝謝你的幫助。 – Bojan