我有一个令我困惑的问题。我有一个如下定义的 Durandal 视图模型,但是this
当我逐步执行代码时,它的值和其他变量和函数会在各处进行更改和更改。
我已经在下面评论了,因为它更容易在代码中移动时显示各种值。
define(['durandal/plugins/router'], function (router) {
var _outerRouter = router;
var _outerSelf = this;
var viewModel = function () {
var _self = this;
var _router = router;
var _searchCriteria = ko.observable('');
var _searchResults = ko.observableArray([]);
var _messages = ko.observableArray([]);
this.searchCriteria = _searchCriteria;
this.searchResults = _searchResults;
this.messages = _messages;
this.search = function () {
//
// When called from the view bindings:
// > this = viewModel
// > _self = _outerSelf = _outerRouter = undefined
// > _router = defined
//
var that = this;
//
// N.B. I set callback context to the viewModel
//
var req = $.ajax({
url: '../api/v1/things',
dataType: 'json',
context: this,
data: {
searchCriteria: this.searchCriteria()
}
})
.done(function (results, status, request) {
//
// When called back:
// > this = viewModel
// > _self = _outerSelf = _outerRouter = undefined
// > _router = defined
//
this.searchResults.removeAll();
this.messages.removeAll();
//
// Now when calling:
// > doShowResult = showResult = undefined
// > this.showResult = defined (have to use 'this')
// > displayMultipleResults = defined
//
if (results.length == 1) {
this.showResult(results[0]);
}
else {
displayMultipleResults(results);
}
});
function displayMultipleResults(results) {
//
// When called from ajax.done():
// > this = Window ?!?!
// > that = viewModel
// > _self = _outerSelf = _outerRouter = undefined
// > _router = defined
//
that.messages.push({ title: 'Found Lots of Things', body: "Please select...blah blah blah", type: 'info' });
for (var i = 0; i < results.length; i++)
that.searchResults.push(results[i]);
};
};
function doShowResult(result) {
//
// When called from ajax.done():
// > this = viewModel
// > _self = _outerSelf = _outerRouter = undefined
// > _router = defined
//
// and then
//
// When called from the view bindings:
// > this = the bound searchResult object
// > _self = _outerSelf = _outerRouter = undefined
// > _router = defined
//
_router.navigateTo('show-my-thing');
}
this.showResult = doShowResult;
};
return viewModel;
});
这是它必然的观点:
<div>
<div class="container-narrow">
<div class="row-fluid">
<div class="span12">
<h3>Search</h3>
<p>Enter search criteria...</p>
<div class="control-group">
<input type="text" class="input-block-level" placeholder="Criteria" data-bind="value: searchCriteria"/>
</div>
<div class="pull-right">
<button class="btn btn-primary" data-bind="click: search">
<i class="icon-search icon-white"></i> Search
</button>
</div>
</div>
</div>
<br />
<!-- ko foreach: messages -->
<div class="row-fluid">
<div class="alert" data-bind="css: { 'alert-error': type == 'error', 'alert-info': type == 'info', 'alert-success': type == 'success' }">
<strong data-bind="text: title"></strong> <span data-bind="text: body"></span>
</div>
</div>
<!-- /ko -->
<!-- ko foreach: searchResults -->
<div class="row-fluid">
<div class="span12 well well-small">
<div class="span10 search-result">
<label>Resut:</label> <span data-bind="{text: $data}"></span><br />
</div>
<div class="span2">
<button class="btn btn-mini btn-success pull-right" data-bind="click: $parent.showResult">
View
</button>
</div>
</div>
</div>
<!-- /ko -->
</div>
</div>
我的主要问题是:
为什么我可以在任何地方访问
_router
但不能访问_self
(或任何其他变量(_searchCriteria 等)?当执行在内部
ajax.done()
并且this
等于 viewModel 的值但在进入 displaySearchResult 之后this
等于 Window 对象时,如何?当在里面
ajax.done()
doShowResult
并且showResult
是undefined
但工作正常时this.showResult
,肯定是否this
定义了?viewModel
showResult
幸运的是,在这种情况下,我只需要导航
doShowResult
并_router
在我从视图绑定和视图绑定调用时定义ajax.done
。但是,如果我需要从视图模型中访问一个值——如果从视图绑定中调用,这将不可用——我如何更改绑定或代码以支持这一点(最好以非 hacky 方式)?
预先感谢任何人都可以对此有所了解。