你可以採取幾種方法,我在下面列舉。
對於以下所有示例,請考慮項目是選擇的主題。
噴射(NO VIEW)
通過這種方法,我們注入ProjectsServices模塊(單)到項目模塊(實例)。但是,只有項目服務不提供一個或多個視圖時,此方法纔有效。下面,我會告訴你如果我們的服務模塊本身也提供一個或多個視圖,我們可以做些什麼。
ProjectsServices視圖模型(singleton)的 sevicesProjects.js
define('projectsServices', [],
function() {
var myData = null; //this may or may not be an observable
return {
myData: myData //we return an object literal, which is what makes this module a singleton
};
}
);
項目視圖模型(實例) 項目。JS
define('projects', ['projectsServices'],
function(services) {
//Constructor
var Projects = function() {
this.myData = ko.observable(); //this may or may not be an observable
};
Projects.prototype.activate = function (activationData) {
this.myData(services.myData);
};
Projects.prototype.detached = function() {
services.myData = this.myData(); /store back to the services module for later use
};
return Projects; //we return a constructor function, which is what makes this module an instance
}
);
主機 - 客戶機(VIEW)
通過這種方法,所述項目模塊由ProjectsServices模塊的內部,並且我們通過myData
來回通過可觀察到的上activationData
。此外,這種方法假定服務模塊不僅提供代碼服務,而且還提供查看服務。彈出其他表單的全局「添加聯繫人」表單是基於視圖的服務模塊的一個示例。而且,「添加聯繫人」視圖當然會有一個viewModel,它代表添加聯繫人的代碼服務。
ProjectsServices視圖模型(singleton)的 servicesProjects.js
define('projectsServices', [],
function() {
var myData = ko.observable(); //should be an observable
}
);
ProjectsServices查看 servicesProjects.html
/*We bring in the Projects module through composition and pass in the observable, `myData`, itself (not `myData()`, but `myData`)*/
<div>
<div data-bind="compose: {model: 'viewmodels/projects', activationData: myData}">
</div>
</div>
項目視圖模型(實例) projects.js
define('projects', [],
function() {
//Constructor
var Projects = function() {
this.myDataLocal = ko.observable(); //this may or may not be an observable
this.myDataFromServices = null;
};
Projects.prototype.activate = function (activationData) {
this.myDataFromServices = activationData
this.myDataLocal(activationData());
};
Projects.prototype.detached = function() {
this.myDataFromServices(this.myDataLocal()); /store back to the services module for later use
};
return Projects; //we return a constructor function, which is what makes this module an instance
}
);
項目視圖 projects.html
/*There are infinite number of ways to bind to your myDataLocal*/
<div>
<div data-bind="text: myDataLocal}">
</div>
</div>
發佈 - 訂閱
通過這種方法,我們利用Durandal的內置酒吧/分設施通過app
。這種方法可以用於上面給出的注入或主機客戶端。策略是發佈來自實例模塊的activate
處理程序的請求消息,並且在同一處理程序中接收回復消息,這兩個消息的目的是請求並提供myData
(假設其早先被保存)。當我們準備將myData
保存回服務模塊時,我們會發送另一個消息myData
作爲有效負載。
ProjectsServices視圖模型(單) servicesProjects.js
define('projectsServices', ['durandal/app'],
function(app) {
var
myData = null, //this may or may not be an observable
activate = function() {
app.on('requestForMyData').then(function() {
app.trigger('responseMyData', myData);
});
app.on('storeMyData').then(function (data) {
myData = data; //where 'data' is the payload
});
},
detached = function() {
app.off('requestForMyData');
app.off('storeMyData');
};
return {
myData: myData, //we return an object literal, which is what makes this module a singleton
activate: activate,
detached: detached
};
}
);
項目視圖模型(實例) projects.js
define('projects', ['durandal/app'],
function(app) {
//Constructor
var Projects = function() {
this.myData = ko.observable(); //this may or may not be an observable
};
Projects.prototype.activate = function() {
var that = this;
app.on('responseMyData').then(function (data) {
that.myData(data);
});
app.trigger('requestForMyData'); //no payload
};
Projects.prototype.detached = function() {
app.trigger('storeMyData', this.myData());
app.off('responseMyData');
};
return Projects; //we return a constructor function, which is what makes this module an instance
}
);
的觀點並不改變在這種情況下,如此他們不在這裏提供。
消息總線
這種方法幾乎是相同的發佈 - 訂閱方法,不同之處在於我們使用一個客戶端的消息總線,如postal.js。你會看到更精緻的。它也恰好是我們在生產中採用的方法。這種方法應該與上面的主機 - 客戶端方法一起使用,只是我們只是傳遞一個消息通道,而不是數據本身。
- 您可以下載postal.js here。
- 請與我(@estaylorco)在Github上與Jim Cowart(@ifandelse)交流here,here和here。
- 查看postal.request-response的RC(我做了而不是,因爲它在預覽中使用),以及我在那裏的交流。 postal.request-response是我所要求的(雙向頻道),它僅適用於您正在使用的場景。它極大地簡化了請求響應場景。
ProjectsServices視圖模型(singleton)的 servicesProjects.js
define('projectsServices', ['postal'],
function(postal) {
var
outletMessageChannel = 'someuniqueidentifier',
subscriptions = [],
myData = null, //this may or may not be an observable
activate = function() {
var that = this;
subscriptions.push(postal.subscribe({
channel: outletMessageChannel,
topic: 'request.mydata',
callback: function() {
postal.publish({
channel: outletMessageChannel,
topic: 'response.mydata',
data: that.myData
});
}
}));
subscriptions.push(postal.subscribe({
channel: outletMessageChannel,
topic: 'store.mydata',
callback: function (data) {
that.myData = data;
}
}));
},
detached = function() {
//I'm using underscore.js here, but you can use any approach to iterate over subscriptions
_.each(subscriptions, function(sub) {
sub.unsubscribe();
sub.callback = null;
sub = null;
});
subscriptions = null;
};
return {
myData: myData, //we return an object literal, which is what makes this module a singleton
activate: activate,
detached: detached
};
}
);
ProjectsServices查看 servicesProjects.html
/*We bring in the Projects module through composition and pass in the message channel*/
<div>
<div data-bind="compose: {model: 'viewmodels/projects', activationData: outletMessageChannel}">
</div>
</div>
項目視圖模型(實例) projects.js
define('projects', ['postal'],
function(postal) {
//Constructor
var Projects = function() {
this.subscriptions = [];
this.outletMessageChannel = '';
this.myData = ko.observable(); //this may or may not be an observable
};
Projects.prototype.activate = function (activationData) {
this.outletMessageChannel = activationData;
var that = this;
subscriptions.push(postal.subscribe({
channel: this.outletMessageChannel,
topic: 'response.mydata',
callback: function (data) {
that.myData(data);
}
}));
postal.publish({
channel: this.outletMessageChannel,
topic: 'request.mydata',
data: null //no payload
});
};
Projects.prototype.detached = function() {
postal.publish({
channel: this.outletMessageChannel,
topic: 'store.mydata',
data: this.myData()
});
//I'm using underscore.js here, but you can use any approach to iterate over subscriptions
_.each(this.subscriptions, function(sub) {
sub.unsubscribe();
sub.callback = null;
sub = null;
});
this.subscriptions = null;
};
return Projects; //we return a constructor function, which is what makes this module an instance
}
);
注意,項目視圖不會在這種情況下發生變化,所以這裏不包括它。
感謝您的詳細解答。我會試試看。 – neo