下面小編就為大家分享一篇在knockoutjs 上自己實現的flux方法,具有很好的參考價值,希望對大家有幫助。一起跟著小編過來看看吧
在knockoutjs 上實作 Flux 單向資料流 狀態機,主要解決多個元件之間對資料的耦合問題。
一、其實簡單
flux的設計理念和實現方案,很大程度上人借鑒和參考了Vuex的實現,只是簡化了某些過程,資料流向圖如下:
從上圖,中以看出資料的改變是單向循環的。我想這就是Flux理念的核心。 Vuex中對Action規範為Action和Mutation,由action去觸發Mutation,action是可以非同步的,而Mutation則是同步更新。而我在設計ko的Flux時,去掉了Mutation這個環節,是因為我理解為,異步的請求一般情況下都是與api接口有關係,這塊內容存在極大的變化性,應該從業務或項目架構上做一層區分。
二、如果使用
當然,flux只是針對knockoutjs的,所以你必須在使用之前引入knockoutjs。 flux主要的方法與物件
2.1 靜態方法
#方法 | ##說明 |
flux.use | 在require模式下,將flux與ko做關聯的方法,當然他必須先與createStore方法呼叫。 |
flux.createStore | 建立一個store(狀態器)實例,當然此方法是有回傳值,他的回傳值可以呼叫register方法註冊到指定的網域上,但第一次呼叫此方法時是建立rootStore(根狀態器),他不允許被註冊到網域的。 |
2.1.1 flux.createStore參數格式
參數名稱 | 說明 |
state | 狀態器相關狀態資料 |
actions | 更改state上的狀態法,方法的第一個參數為state,第二參數開始則為傳入的相關內容 |
#getters | 取得state上的相關狀態數據,當然回傳是一個ko監控物件。 |
2.2 實例方法
#createStore方法的執行,會在ko實例上增加$store屬性,此屬性是狀態器的實例對象,在任何位置都可以呼叫他的dispatch來觸發事件。
方法 | 說明 |
#register | 建立和註冊一個狀態域,域與域之間是相互獨立儲存的,域之間action或get名稱是可以重複的 |
unRegister | 移除一個狀態域 |
#dispatch | 根據actionName呼叫指定的action,無回傳值 |
get | 根據getName呼叫指定的get,有回傳值 |
#三、簡單的使用
本範例定義了四個ko綁定區域,分別是:app1, app2, app3, app4。實作app4中對name的改變自動影響到app1,而app3對清單的改變自動影響到app2。
3.1 定義vm並初始化store
function ViewModel(){
this.list = ko.observableArray();
this.name = ko.observable('无名氏');
this.count = ko.computed(function(){
//必须用this,这个时候ko.$store还没创建完成,应该ko.computed创建时会执行一次此处
//如果是子vm依赖主vm,还是可以用ko.$store的
return this.list().length + '个数'; //需要对监控对象求值,否则computed不能有效
},this);
}
var fullVm = new ViewModel();
var index = 1;
fullVm.vf={
add: function(){
ko.$store.dispatch('addClass',{title: 'title' + (index++)});
}
}
var opt = {
state: {
class: fullVm
},
actions:{
"setName":function(state, name){
state.class.name(name);
},
"addClass":function(state, classInfo){
state.class.list.push(classInfo);
}
},
getters:{
"getName":function(state){
return state.class.name;
}
}
}
flux.createStore(opt);
登入後複製
根據上述程式碼,首先定義了ViewModel的一個類,並建立了一個fullVm的一個實例,然後直接在fullVm實例上增加了add方法。
opt的state所引用的是fullVm,其中也配置了actions和getters相關對象,然後呼叫flux.createStore(opt)方法。建立一個store,並關聯到ko.$store物件上。
3.2 與檢視綁定
html程式碼:
<p id="app1">
app1:
<span data-bind="text:ko.$store.get('getName')"></span>
</p>
<p id="app4">
app4:
<input type="text" data-bind="value:name" />
<button type="text" data-bind="click:changeName" >改变名字</button>
<span data-bind="text:ko.$store.state.class.name"></span>
</p>
<hr>
<p id="app2">
app2:
<ul data-bind="foreach:list" >
<li data-bind="text:title" ></li>
</ul>
</p>
<p id="app3">
app3:
<button type="button" data-bind="click:vf.add" >添加</button>
<span data-bind="text:count"></span>
</p>
登入後複製
js程式碼:
var app1 = ko.applyBindings(fullVm, document.getElementById("app1"));
var app2 = ko.applyBindings(fullVm, document.getElementById("app2"));
var app3 = ko.applyBindings(fullVm, document.getElementById("app3"));
//测试两个vm之间的依赖 解藕
var app4 = ko.applyBindings({
name: ko.observable(),
changeName:function(data,event){
ko.$store.dispatch('setName', this.name());
}
}, document.getElementById("app4"));
登入後複製
##四、網域的實例
#########html程式碼:######<p id="app1">
<span data-bind="text:name" ></span>
</p>
<p id="app2">
<span data-bind="text:name"></span>
<span data-bind="text:full"></span>
<button type="button" data-bind="click:changeName" >换名</button>
</p>
登入後複製
######js程式碼:###### function rootViewModel(){
this.name = ko.observable('root');
}
var rVM = new rootViewModel();
flux.createStore({ state: rVM}); //创建root状态器
var treeNode={
name: ko.observable('node'),
changeName:function(){
ko.$store.areas.treeNode.state.name('新名字');
},
full: ko.computed(function(){
//computed的职责:1. 监控其他对象属性的变化,而影响自身对象(flux解决);2. 合并自身对象的几个属性(在function下,有this可解)
//不能通过ko.$store访问对象本身,因为首次对象本身还没初始化好
var store = ko.$store;
//(store.areas.treeNode? store.areas.treeNode.state.name() : '') 这样也是不行,因为解决第一次通不过,后面肯定不行
return store.state.name();
})
}
ko.$store.register('treeNode', flux.createStore({ state: treeNode})); //创建子状态机
var app1 = ko.applyBindings(rVM, document.getElementById("app1"));
var app2 = ko.applyBindings(treeNode, document.getElementById("app2"));
登入後複製
###上面是我整理給大家的,希望未來會對大家有幫助。 ######相關文章:#########在nodejs中如何調取微信收貨位址############在nodejs中如何實作微信支付#### #########詳細解讀Vuejs中響應式原理#############使用nodeJS如何實作微信分享######
以上是在knockoutjs上如何實作flux的詳細內容。更多資訊請關注PHP中文網其他相關文章!