Knockout.js Breeze多次查询淘汰可观测数组
我被困在这一点上,无法继续 我正在通过以下方式为搜索表单创建ViewModel:Knockout.js Breeze多次查询淘汰可观测数组,knockout.js,asp.net-mvc-4,breeze,Knockout.js,Asp.net Mvc 4,Breeze,我被困在这一点上,无法继续 我正在通过以下方式为搜索表单创建ViewModel: var viewModel = new SearchViewModel("Api/Vehicle", "Vehicles"); ko.applyBindings(viewModel); 稍后,当用户单击“查找”按钮时,将触发“查找”方法(此处简化): query*方法仅将数据放入Knockout.js可观察数组中: function querySucceeded(data) { data.results.
var viewModel = new SearchViewModel("Api/Vehicle", "Vehicles");
ko.applyBindings(viewModel);
稍后,当用户单击“查找”按钮时,将触发“查找”方法(此处简化):
query*方法仅将数据放入Knockout.js可观察数组中:
function querySucceeded(data) {
data.results.forEach(function (item) {
self.results.push(item);
});
return true;
}
function queryFailed(error) {
var erroboj = { message: error.message };
self.errors.push(erroboj);
return false;
}
问题是querySucceeded从未被调用,Knockout.js的数据也从未更新,从而触发数据绑定
我做错了什么
这是ViewModel。还有点不完整和模糊。 我想我没有正确理解breeze query Promiss:
/*global $, jQuery, ko, breeze, bootstrap */
function SearchViewModel(serviceName, actionName) {
"use strict";
var self = this;
self.serviceName = serviceName;
self.actionName = actionName;
self.errors = ko.observableArray([]);
self.results = ko.observableArray([]);
self.CreateEntity = function (entityTypeName) {
var entityType = self.manager.metadataStore.getEntityType(entityTypeName),
newEntity = entityType.createEntity();
return self.manager.addEntity(newEntity);
};
function querySucceeded(data) {
// Here the function I want to run
data.results.forEach(function (item) {
self.results.push(item);
});
return true;
}
function queryFailed(error) {
var erroboj = { message: error.message };
self.errors.push(erroboj);
return false;
}
function addError(errorMessage) {
var erroobj = { message: errorMessage };
self.errors.push(erroobj);
}
function NoFilterDefined(Condition) {
var s = "Find(): Funcao Filter() not implemented:";
addError(s);
Condition = null;
throw new Error(s);
}
try {
self.Filter = NoFilterDefined;
self.Find = function () {
debugger;
var Condition = breeze.Predicate;
var predicate;
self.errors.removeAll();
try {
predicate = self.Filter(Condition);
} catch (errorf) {
var sf = "Find(): Error calling Filter() in {actionName}: {error}";
sf = sf.replace("{error}", errorf.message);
sf = sf.replace("{actionName}", predicate.toString());
addError(sf);
throw new Error(sf);
}
var query = breeze.EntityQuery
.from(self.actionName)
.where(predicate);
try {
debugger;
var promisse = self.manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
// Here I suppose the .then(querySucceeded) already was called
} catch (errore) {
var se = "Find(): Erro calling query in {actionName}: {error}";
se = se.replace("{error}", errore.message);
se = se.replace("{actionName}", self.actionName);
addError(se);
throw new Error(se);
}
};
self.FetchMetadata = function () {
//self.manager.fetchMetadata() // not working?
// .fail(self.queryFailed);
var query = breeze.EntityQuery
.from(actionName)
.where("1", "==", "0"); // Just to get metadata
var execution = self.manager.executeQuery(query);
execution.then(function (data) {
data = null;
});
return true;
};
self.SetParameters = function (parameters) {
self.parameter = ko.observable(parameters);
};
self.store = new breeze.MetadataStore(); // define metadataStore for all managers
self.manager = new breeze.EntityManager({
serviceName: self.serviceName,
metadataStore: self.store
});
} catch (error) {
var erroboj = { message: error.message };
self.Errors.push(erroboj);
}
}
try {
// Uncomment //debugger to debug this script. Use Visual Studio an IE to debug.
//debugger;
var viewModel = new SearchViewModel("Api/Vehicle", "Vehicles");
var parameter = {
Id: "AAB-1113",
Type: "CIF"
};
viewModel.SetParameters(parameter);
viewModel.Filter = function (Condition) {
"use strict";
var self = this;
var where = Condition.create("Type", "==", self.parameter.Type);
if (parameter.Id !== null) {
where = where.and("Id", "contains", self.parameter.Id);
}
return where;
};
ko.applyBindings(viewModel);
} catch (error) {
alert("Erro de codigo:".concat(error.message));
}
最重要的问题是:为什么根本不调用
querysucceed
方法?我假设您的queryFailed
也没有被调用?其中一个应该被击中
您是否已使用调试器验证两个方法都未调用?您确定有来自服务器的任何查询结果吗?我首先从网络流量日志中复制HTTP GET请求,然后在浏览器地址栏中重播它。只有在您确定服务器正在返回某些内容之后,我才能继续处理查询结果
注意:我刚刚在您的问题陈述下面看到了完整的ViewModel。 在看到完整的虚拟机之前,我写下了我的回复,几乎从头开始。但我保留了我最初的答案,因为知道如何解决一个谜很重要,而不仅仅是回答它 问题几乎可以肯定是你的谓词。如果删除
where(…)
子句,我敢打赌您会看到结果。我敢打赌,谓词设置的条件永远不会为真,因此您永远不会显示任何结果
在self.Find中
将谓词初始化为Breeze谓词
构造函数。我认为你永远都不想那样做。您可能需要创建一个新实例
你似乎想要创造一个“身份条件”——一个总是真实的条件。这对我来说似乎有点聪明。NoFilterDefined
的实用性和实现对我来说也是一个谜。。。但现在我离手头的事情很远了
为什么不保持letself.Filter()
保持null
,直到出现实际的筛选条件?然后适当地构建查询,可能如下所示:
var query = breeze.EntityQuery.from(self.actionName);
var predicate = self.Filter();
if (predicate) { query = query.where(predicate); }
如果您担心在查询方法返回之前会弄乱data.results
数组(为什么?),可以先复制它self.results(data.results.slice())代码>
次要观点:
- 我强烈建议将这些持久性关注点从ViewModel中移出,并作为一个助手组件,如
dataservice
或datacontext
as
- 据我所知,您不需要任何
fetchMetadata
业务。Breeze在EntityManager的第一次查询时隐式获取元数据。您可以在必要时预取元数据(),但这里没有明显的必要
- 您的
self.Find
方法是否应该将承诺返回给调用方
- 为什么您的
querysucceed
返回true
- 在执行查询之前,是否应清除
self.Find
中的self.results([])
?我通常这样做
- 为什么
queryFailed中的self.errors
是一个可观察的问题。您正在将错误消息推送到错误消息数组中。。。在方法开头清除的数组。为什么是数组?为什么不能观察到一个简单的KO
最重要的问题是:为什么您的查询成功了
方法根本没有被调用?我假设您的queryFailed
也没有被调用?其中一个应该被击中
您是否已使用调试器验证两个方法都未调用?您确定有来自服务器的任何查询结果吗?我首先从网络流量日志中复制HTTP GET请求,然后在浏览器地址栏中重播它。只有在您确定服务器正在返回某些内容之后,我才能继续处理查询结果
注意:我刚刚在您的问题陈述下面看到了完整的ViewModel。
在看到完整的虚拟机之前,我写下了我的回复,几乎从头开始。但我保留了我最初的答案,因为知道如何解决一个谜很重要,而不仅仅是回答它
问题几乎可以肯定是你的谓词。如果删除where(…)
子句,我敢打赌您会看到结果。我敢打赌,谓词设置的条件永远不会为真,因此您永远不会显示任何结果
在self.Find中
将谓词初始化为Breeze谓词
构造函数。我认为你永远都不想那样做。您可能需要创建一个新实例
你似乎想要创造一个“身份条件”——一个总是真实的条件。这对我来说似乎有点聪明。NoFilterDefined
的实用性和实现对我来说也是一个谜。。。但现在我离手头的事情很远了
为什么不保持letself.Filter()
保持null
,直到出现实际的筛选条件?然后适当地构建查询,可能如下所示:
var query = breeze.EntityQuery.from(self.actionName);
var predicate = self.Filter();
if (predicate) { query = query.where(predicate); }
如果您担心在查询方法返回之前会弄乱data.results
数组(为什么?),可以先复制它
self.results(data.results.slice())代码>
次要观点:
- 我强烈建议将这些持久性关注点从ViewModel中移出,并作为一个助手组件,如
dataservice
或datacontext
as
- 据我所知,您不需要任何
fetchMetadata
业务。Breeze隐式获取元数据
function querySucceeded(data) {
self.results(data.results);
};