gpt4 book ai didi

knockout.js - BreezeJS与DurandalJS的集成与如何加载KnockoutJS有关的问题

转载 作者:行者123 更新时间:2023-12-04 04:43:56 25 4
gpt4 key购买 nike

Durandal.JS和Breeze.JS在一起玩会有一些麻烦。 Durandal基于一些库,注意的两个是Require和Knockout。在使用Require引入的模块化模式之前,我的原始项目在Breeze模型上使用了Knockout样式绑定。

在旅途中,我发现Breeze可以与Breeze模型的多个库一起使用,例如Backbone,Knockout,Angular和其他框架。当将Breeze加载为Require模块时,Breeze会检查别名是否存在用于Knockout的模块。该模块名称与Durandal如何别名为Knockout冲突,因为Durandal改用模块名称“ knockout”。

当Breeze加载时,将进行检查以确定如何呈现Breeze模型的数据属性。在我的原始项目中,Breeze将在全局范围内检测到Knockout并将所有属性分配为“ ko.observable()”样式属性。

我如何才能使这些模块正常运行?我尝试了几种Require.JS技巧,例如添加以下Shim:(from this post)

breeze: { deps: ['ko', 'jQuery', 'Q'] }


并添加以下虚拟模块定义:

define('ko', ['knockout'], function (ko) { return ko; });
define('Q', ['q'], function (Q) { return Q; });
define('jQuery', ['jquery'], function ($) { return $; });


在我的main.js中。该组合使Breeze可以运行。我能够针对后端API成功执行查询。

但是,结果不能正确地变为可观察到的淘汰赛。相反,Breeze似乎正在使用本机ES5可观察的属性。虽然这实际上有点酷,但它完全破坏了我现有的模块。

需要注意的是,正如Druandal文档所建议的那样,我将使用Q提供的片段覆盖内部Promise库。

   system.defer = function (action) {
var deferred = Q.defer();
action.call(deferred, deferred);
var promise = deferred.promise;
deferred.promise = function () {
return promise;
};
return deferred;
};


尽管上面的垫片和虚拟模块纠正了此问题,但Q库和jQuery库也出现了这些相同的问题。我不知道下一步该怎么做。

编辑:为响应“显示您的上下文设置”注释:

define([
'breeze',
'q',
'durandal/system',
'lodash'
],
function (breeze, Q, system, _) {
return new function () {
var self = this;

self.create = create;
self.init = init;

var EntityQuery = breeze.EntityQuery;
var BREEZE_URL = '/breeze/AtlasApi/';
var masterManager = new breeze.EntityManager(BREEZE_URL);
self.masterManager = masterManager;

function init() {

return masterManager.fetchMetadata()
.fail(function (error) {
system.error(error);
});
};
function create() {
var manager = masterManager.createEmptyCopy();

return manager;
};
};
});


上面的模块我在AppStart加载一次,并调用Init方法以确保我具有元数据。然后,我在其他地方调用.create()来创建一个空的隔离副本。这在非Require.js环境中效果很好。我使用promises来确保init步骤已经完成。我可以手动运行查询,并且它们可以正常工作,而无需通过Breeze实现实体的方式(同样,作为ES5属性,而不是敲除属性)

最佳答案

看起来您正在尝试通过requireJS加载每个库。我记得,开箱即用的Durandal方法是直接加载第三方脚本(在require之外),并且仅对应用程序脚本使用require。

这简化了事情,但这并不是唯一的方法,很多人想要使用require来加载所有脚本。

我们最近(v.1.4.7)更新了“ Todo-Require”样本,以演示该方法。我意识到这不是Durandal应用,但希望您能找到所需的方向。

我将在此复制我认为对您有帮助的要点。

index.html

...
<body>
<div id="applicationHost"></div>

<!-- Require + main. All scripts retrieved async by requireJS -->
<script data-main="Scripts/app/main" src="Scripts/require.js"></script>
</body>
...


main.js

(function () {
requirejs.config({
paths: {
'breeze': '../breeze.debug',
'jquery': '../jquery-1.8.3.min',
'ko': '../knockout-2.2.0',
'Q': '../q'
}
});

// Launch the app
// Start by requiring the 3rd party libraries that Breeze should find
define(['require', 'ko', 'jquery', 'logger', 'Q'], function (require, ko, $, logger) {
logger.info('Breeze Todo is booting');

// require the 'viewModel' shell
// require '../text' which is an html-loader require plugin;
// see http://requirejs.org/docs/api.html#text
require(['viewModel', '../text!view.html'],

function (viewModel, viewHtml) {
var $view = $(viewHtml);
ko.applyBindings(viewModel, $view.get(0));
$("#applicationHost").append($view);
});
});
})();


请注意,我们如何使用路径来定位库并获得Breeze期望的建立的模块名称。

还要注意,在Breeze本身加载之前,我们强制requireJS加载这些依赖的第三方库。那真的很重要。在Breeze开始寻找它们时,它们必须位于requireJS IoC容器中。如果他们不在,Breeze会认为他们永远不会在那里。

这就是为什么您会看到Breeze将实体属性视为ES5属性的原因。呼叫“上下文设置”中的 define同时加载“ ko”和“微风”。这意味着当Breeze在其自身的初始化阶段寻找'ko'时,无法保证将其加载。

如果在Breeze查找“ ko”时未将其加载,则Breeze会假定您未使用Knockout并返回其本机模型库(“ backingStore”)...将实体构建为ES5属性。这恰好是Angular应用程序的正确选择。这不是KO应用程序的正确选择。

最后,如果Durandal期望模块使用不同的名称(我会为您效忠),请使用requireJS“ map”配置来定义同义词,如下例所示:

requirejs.config({
paths: {
'breeze': '../breeze.debug',
'jquery': '../jquery-1.8.3.min',
'ko': '../knockout-2.2.0',
'Q': '../q'
},
map: {
'*': { 'knockout': 'ko' }
}
});


现在,当Durandal请求“淘汰”时,requireJS会将其映射到(已加载的)“ ko”模块。

这种“地图”技术代替了同样有效的“虚拟模块”方法:

define('knockout', [ko], function (ko) { return ko; });


在查看示例代码时,您可能会想知道此应用何时加载Breeze。答案: viewModel解析后。 viewModel有其自己的依赖项,其中包括 dataservice本身依赖于Breeze。依赖注入不是很棒吗? :-)

另类

您也许还可以通过其他方式解决问题。

根据您的问题,可以启动并运行Breeze和Durandal,但是Breeze模型库似乎已为Breeze的本机“ backingStore”配置,该实体将实体属性写为ES5 getter / setter属性。

您可以在以后的启动过程中(可能是在您第一次与Breeze交互并创建 dataservicedatacontextEntityManager模块中)更改该选择。

在进行第一次微风互动之前,请致电

breeze.config.initializeAdapterInstance("modelLibrary", "ko", true);


这建立了淘汰模式,因为Breeze在创建/实现实体时应使用模型库。此后,将创建具有KO可观察属性的实体。

至关重要的是,在进行此配置更改之前,将剔除加载到requireJS IoC容器中并以“ ko”访问,否则Breeze会引发异常。

不要期望Breeze等到requireJS异步加载了'ko'。适配器初始化是一个同步过程。在微风寻找它之前,必须先装载“ ko”。

杜兰达2.0

我得知Durandal v2.0改变了我在Durandal v.1.x中熟悉的安装模式。我相信我的回答仍然贴切。

我对Durandal v.2不太熟悉。我对此感到很兴奋,部分原因是它提供了使用ES5属性获取器/设置器而不是可观察性函数的可能性。我喜欢那一吨!

这项特定功能(不必使用)的代价是必须在与ES5兼容的浏览器中运行……这意味着您无法在仍流行的IE8中运行。没有ES5属性的polyfill。

大多数(但不是全部)单页应用程序可以在此限制内运行。

不幸的是,根据Durandal的架构师说,在当前的2.0版本中,ES5属性不适用于Breeze。这两个库在争夺那些getter和setter方法。因此,您可以将Durandal v2.0与Breeze一起使用,但现在必须保留可观察的函数属性。

我们希望这个故事在2.1版之前有所改善

总共

希望这些想法和变化能使您走上成功的道路。

关于knockout.js - BreezeJS与DurandalJS的集成与如何加载KnockoutJS有关的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21006421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com