我正在使用看起来非常适合 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);
}
}
};
});
显然这有问题。如果在 async require 调用完成之前调用 show ,那么Dep1
仍然为 null。所以我们并没有真正展示作为目标的依赖关系,显然在这种情况下会抛出 JS 错误。此外,我们仍在使用if
我不喜欢的节目检查,但用例是依赖项可能存在也可能不存在,如果不需要它,我们只是不想要求它,所以我可能无法解决这个问题。还要记住,这model.showDependency
实际上不是一个布尔值。它可以有多个值,这将需要不同的依赖项。为了简单地理解基本问题,我在这里将其剥离。
想法二
这不太稳固,即我认为这甚至行不通,但我考虑过使用 require config.path 的东西。我的想法基本上是有两个配置,以便'./dependency'
指向不同的地方。问题在于,尽管model.showDependency
配置的值是相同的,但需要配置,因此无法在运行时更改它。也许可以在这里完成一些魔术,例如定义单独的视图目录路径并使用工厂类型对象返回我们关心的对象,但因为这最终会导致在Idea中出现相同的异步行为,所以我不认为给我买任何东西(基本上是一样的)。
思路三
让依赖基于model.showDependency
属性返回null。这可能是目前最好的解决方案。我仍然坚持一些if
s 但我认为这不会消失。这也可以防止调用初始化代码。
有更好的想法吗?