私もこれに苦労しており、ビュー関連のものをviewModelに入れるのが臭いことに同意します。あなたが話していることをする必要があった理由は、委任されたイベント ハンドラーをアタッチすることでした。これは、提案されているように、カスタム バインディングまたはウィジェットを使用して行うことはできません。
同僚と私が思いついた最善の解決策はviewAttached
、viewModel からイベントを伝達し、「ビュー ファイル」でイベントをリッスンすることでした。
例として「awesome」という名前のビューを使用すると、次のような命名規則を使用しています。
- モデルの表示- viewmodels/awesome.js
- 表示- views/awesome.html
- ファイルを表示- views/awesome.html.js
これは、私たちが行っていることの単純化されたバージョンです。
ビューモデル/awesome.js:
define([
"durandal/app",
"durandal/system",
// require the view file; note we don't need a reference to it,
// we just need to make sure it's loaded
"views/myView.html"
],
function (app, sys) {
var viewModel = {
// whatever
};
viewModel.viewAttached = function(view) {
// Create a namespace for the event
var eventNamespace = sys.getModuleId(viewModel)
.replace("viewmodels", "")
.replace("/", ".");
// This will evaluate to 'awesome.viewAttached'
var eventName = eventNamespace + ".viewAttached";
// Trigger the event and pass the viewModel and the view
app.trigger(eventName, viewModel, view);
};
return viewModel;
});
ビュー/awesome.html.js:
define([
"durandal/app"
],
function (app) {
var module = {
viewAttached: function(viewModel, view) {
// do your thing! make sure any selectors you use use the view as the parent selector,
// because you're not guaranteed that your view is in the DOM (only that it's attached
// to its parent).
var $submit = $("#submit", view);
}
};
// wire-up
app.on("awesome.viewAttached", module.viewAttached);
// export
return module;
});
それが役立つことを願っています。