需要 JS 依赖项覆盖以实现可配置的依赖项注入
RequireJS dependency override for configurable dependency injection
我正在使用的东西似乎非常适合DI,但它被添加到一个现有的框架中,在编写它时没有考虑到这一点。定义依赖项的配置来自后端模型。实际上,在这一点上它不是一个完整的配置,它基本上包含一个可用于确定特定视图是否可用的键。
我正在使用require,所以依赖项看起来像这样
// Dependency
define(['./otherdependencies'], function(Others) {
return {
dep: "I'm a dependency"
};
});
现在喷油器看起来像这样
// view/injector
define([
'./abackendmodel',
'./dependency'
], function(Model, Dependency) {
return {
show: function() {
if (model.showDepency) {
var dep = new Dependency();
this.$el.append(dep);
}
}
};
});
这与实际代码相去甚远,但重要的部分是 require 的工作原理。请注意,在注入器代码中,依赖项是必需的,并且在 show 方法中使用,但前提是模型说应该显示它。问题在于,依赖项可能需要的其他内容在不应该显示时不可用。因此,我真正想做的是不必指定该依赖项,除非model.showDependency
为真。我想出了几个想法,但没有我喜欢的。
想法一根据该模型属性进行另一个异步要求调用。所以喷油器看起来像这样。
// Idea 2 view/injector
define([
'./abackendmodel'
], function(Model) {
var Dep1 = null;
if (model.showDepedency) {
require([
'./dependency'
], function(Dependency) {
Dep1 = Dependency;
});
}
return {
show: function() {
if (Dep1) {
var dep = new Dep1();
this.$el.append(dep);
}
}
};
});
显然,这有问题。如果在异步需求调用完成之前调用 show,则Dep1
仍将为 null。所以我们并没有真正显示依赖性,这是一个目标,显然在这种情况下会抛出JS错误。此外,我们仍在使用我不喜欢的if
检查节目,但用例是依赖项可能存在也可能不存在,我们只是不想在不需要时需要它,所以我可能无法绕过它。另请记住,model.showDependency
实际上不是布尔值。它可以有多个值,这些值需要不同的依赖项。为了便于理解基本问题,我只是在这里将其剥离。
想法二这不太固化,即我认为这甚至不起作用,但我已经考虑过使用所需的 config.path 东西。我的想法基本上是有两个配置,以便'./dependency'
指向不同的地方。问题是,尽管model.showDependency
值是什么,但配置是相同的,因此无法在运行时更改它。也许这里可以做一些魔法,例如定义单独的视图目录路径并使用工厂类型对象返回我们关心的对象,但由于这最终会导致 Idea one 中相同的异步行为,我认为这不会给我带来任何东西(它基本上是相同的(。
想法三使依赖项基于 model.showDependency
属性返回 null。这可能是目前最好的解决方案。我仍然坚持一些if
,但我认为这不会消失。此外,这会阻止调用初始化代码。
有什么更好的主意吗?
为什么不尝试使用承诺来加载依赖项呢?
您有两种选择,具体取决于代码需要的工作方式。
选项 1(为模块"view/injector"的结果返回一个承诺,这个承诺的结果将是上面显示的当前对象结果。
选项 2(使用承诺加载依赖项,然后在解决承诺后执行逻辑。
下面是选项 2 的示例,使用 jQuery 样式延迟。 我通常更喜欢当.js或 Q. 如果追加顺序很重要,此示例可能会崩溃。
// Option 2
define([
'./abackendmodel'
], function(Model) {
var dep1Promise = null;
if (model.showDepedency) {
var dep1Deferred = $.Deferred();
dep1Promise = dep1Deferred.promise();
require([
'./dependency'
], function(Dependency) {
dep1Deferred.resolve(Dependency);
}, dep1Deferred.reject); // Optionally reject the promise if there is an error finding the dependency.
}
return {
show: function() {
if (dep1Promise) {
dep1Promise.then(function(Dep1) {
var dep = new Dep1();
this.$el.append(dep);
});
}
}
};
});
- 在自定义mean.io包中使用angular-chart.js作为依赖项
- 为什么Airbnb风格指南说不鼓励依赖函数名称推断
- RequireJS向模块传递配置总是返回undefined
- 将依赖外部库的UMD模块与browserfy捆绑在一起
- 如何将本地依赖项添加到npm项目中
- 如何配置分析以将数据发送到我自己的服务器
- 扩展jQuery插件以更改配置
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- jquery中的复选框依赖项
- 为什么react/redux前端项目在package.json中包含生产依赖项
- 需要 JS 依赖项覆盖以实现可配置的依赖项注入
- 配置依赖于另一个服务angularjs的服务
- 如果我使用r.js优化我的RequireJS项目,我必须改变路径和依赖配置吗?
- Angular - Access配置注入的依赖项
- 在ASP上使用JavaScriptSerializer进行Unicode字符转义.. NET MVC依赖于配置
- 用mocha测试依赖于环境变量process.env.APP_ENV的配置模块
- JavaScript文件依赖于Yii2中的JavaScript代码块(用于dojo配置)
- 如何“将服务文件添加为依赖项”?在我的Angular 2项目的Karma配置中
- 是否有可能从要求优化器构建配置中排除模块,但该模块及其依赖项分别优化
- 无法在Restangular配置函数(AngularJs)中传递依赖项