根据上面的评论,我们在使用该customJsonResultsAdapter
方法时错过了让 Breeze 连接所有导航属性等。本质上,我们想要 Breeze 的优点,而不需要将所有实体属性都变成 Knockout observables 的开销(直到我们需要它们)。
编辑:由于以前的自定义模型库方法中的错误,答案已更改为使用两个实用程序函数
作为替代解决方案,我们更改为使用内置的 Breeze backingStore
modelLibrary适配器,并添加了几个函数以在需要时使单个实体Knockout 可观察。这样做的后果是:
- 这是一种“精简”方法,非常适合只读数据。
- Breeze将拦截对这些属性的更改并像往常一样跟踪它们。
- 我们仍然可以使用 Knockout 绑定lite实体,但是由于默认情况下属性不可观察,因此如果属性值发生更改,则网页不会更新。
当用户确实想要编辑实体时,我们会执行类似...
function startEditing(entity, uiElement) {
if (!breeze.utils.isObservable(entity)) {
breeze.utils.makeObservable(entity);
ko.applyBindings(entity, uiElement);
}
几个重要的注意事项:
- 我们需要
applyBindings
在使实体可观察之后重新进行,以便属性更改触发 Knockout 以更新 UI。
- 我们的 makeObservable 函数使用Steve Sanderson 的 ES5 插件,因此我们的标记绑定中不需要括号(尽管仅限于 IE9+)
我在下面包含了我们的自定义函数的代码。在加载上面的 Knockout、Breeze 和 Steve 的插件后,您需要包含此代码。
// Add a function to make an individual Breeze entity observable.
// Requires the Knockout ES5 plugin from http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax/
// Note: Breeze must be configured to use it's built in backingStore adapter:
// breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
(function () {
var utils = breeze.utils = breeze.utils || {};
utils.makeObservable = function (entity) {
var bs = entity && entity._backingStore;
if (!bs) {
throw new Error("Only entities provided by the backingStore adapter can be made observable");
}
ko.track(bs);
};
utils.isObservable = function (entity) {
var result = false,
bs = entity && entity._backingStore;
if (bs) {
var propNames = Object.getOwnPropertyNames(bs);
if (propNames.length > 0) {
result = !!ko.getObservable(bs, propNames[0]);
}
}
return result;
};
})();