從上圖,中以看出資料的改變是單向循環的。我想這就是Flux理念的核心。 Vuex中對Action規範為Action和Mutation,由action去觸發Mutation,action是可以非同步的,而Mutation則是同步更新。而我在設計ko的Flux時,去掉了Mutation這個環節,是因為我理解為,異步的請求一般情況下都是與api接口有關係,這塊內容存在極大的變化性,應該從業務或項目架構上做一層區分。
方法 | 說明 |
#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如何實作微信分享######