作为一个个人项目,我试图创建自己的轻量级版本的依赖注入JavaScript - 有些人可能不同意调用这个DI,因为它没有接口,但我得出的结论是接口过度杀伤在JS中,因为我们可以很容易地键入检查。我已经看过Angular的来源,但我觉得我的项目可能有些过于复杂,而且无论如何我都有兴趣尝试自己的学习经历。
我的问题是,从根本上说,我试图实现的语法是否不可能?
我将解释我的语法目标,然后提供错误和代码段,在下面我将发布完整代码。
我希望创建一个组件,并注入依赖项,就像这样,一切都是组件,任何东西都可以是依赖。我用字符串路径创建了范围,使用"/scopeName/subScopeName:componentName"
来选择范围,以便代码用户可以在以简单方式定义组件时选择范围,使用":"
从范围中选择组件。
var JHTML = new Viziion('JHTML');
JHTML.addScope('/generate');
/* ...snip - see full code for the process component - snip ... */
JHTML.addComponent('/generate:init', function (jsonInput, process) {
var html = process(jsonInput);
return html;
}).inject([null, '/generate:process']);
inject
函数只按照组件参数的顺序获取一组组件路径。 null
可用于跳过,允许直接参数输入,如上所示。
我也有一些我称之为钩子的东西,它是存储在某个地方的组件,然后是一个函数returnUserHandle
,它将返回一个只包含钩子的对象,所以所有的函数都是隐藏在闭包中,你可以只为可用的方法提供代码用户,干净简单,并且可以生成最终产品作为库而无需布线,不需要我的DI框架作为依赖。希望这是有道理的。
现在,运行代码(这是一个非常简单的库,通过解析JSON结构来生成HTML)我在行process
中得到var html = process(jsonInput);
未定义的错误。我无法理解这是一个基本的设计问题,还是只是一个bug。也许这种语法是不可能的,我希望你能告诉我。
以下是代码,a link to the JS Bin。
/* Dependency Injection Framework - viziion.js */
function Viziion(appName) {
if (typeof appName == 'string') {
var that = this;
this.name = appName;
this.focus = null;
this.scope = {
'/': {
'subScopes': {},
'components': {}
}
};
this.hooks = {};
this.addScope = function(scopeName) {
if (typeof scopeName == 'string') {
var scopeArray = scopeName.split('/');
var scope = that.scope['/'];
for (var i = 0; i < scopeArray.length; i++) {
if (scopeArray[i] !== "") {
if (scope.subScopes[scopeArray[i]]) {
scope = scope.subScopes[scopeArray[i]];
} else {
scope.subScopes[scopeArray[i]] = {
'subScopes': {},
'components': {}
};
}
}
}
} else {
throw 'Scope path must be a string.';
}
return that;
};
this.addComponent = function(componentName, func) {
if (typeof componentName == 'string') {
var scopeArray = componentName.split(':');
if (scopeArray.length == 2) {
var scope = that.scope['/'];
var scopeName = scopeArray[1];
scopeArray = scopeArray[0].split('/');
for (var i = 0; i < scopeArray.length; i++) {
if (scopeArray[i] !== "") {
if ((i + 1) === scopeArray.length) {
scope.components[scopeName] = func;
that.focus = scope.components[scopeName];
} else if (scope.subScopes[scopeArray[i]]) {
scope = scope.subScopes[scopeArray[i]];
} else {
throw 'Scope path is invalid.';
}
}
}
} else {
throw 'Path does not include a component.';
}
} else {
throw 'Component path must be a string1.';
}
return that;
};
this.returnComponent = function(componentName, callback) {
if (typeof componentName == 'string') {
var scopeArray = componentName.split(':');
if (scopeArray.length == 2) {
var scope = that.scope['/'];
var scopeName = scopeArray[1];
scopeArray = scopeArray[0].split('/');
for (var i = 0; i < scopeArray.length; i++) {
if (scopeArray[i] !== "") {
if ((i + 1) === scopeArray.length) {
//console.log('yep1');
//console.log(scope.components[scopeName]);
callback(scope.components[scopeName]);
} else if (scope.subScopes[scopeArray[i]]) {
scope = scope.subScopes[scopeArray[i]];
} else {
throw 'Scope path is invalid.';
}
}
}
} else {
throw 'Path does not include a component.';
}
} else {
throw 'Component path must be a string2.';
}
};
this.addHook = function(hookName, func) {
if (typeof hookName == 'string') {
that.hooks[hookName] = func;
that.focus = that.hooks[hookName];
} else {
throw 'Hook name must be a string.';
}
return that;
};
this.inject = function(dependencyArray) {
if (dependencyArray) {
var args = [];
for (var i = 0; i < dependencyArray.length; i++) {
if (dependencyArray[i] !== null) {
that.returnComponent(dependencyArray[i], function(dependency) {
args.push(dependency);
});
}
}
console.log(that.focus);
that.focus.apply(null, args);
return that;
}
};
this.returnUserHandle = function() {
return that.hooks;
};
} else {
throw 'Viziion name must be a string.';
}
}
/* JSON HTML Generator - A Simple Library Using Viziion */
var JHTML = new Viziion('JHTML');
JHTML.addScope('/generate');
JHTML.addComponent('/generate:process', function(children) {
var html = [];
var loop = function() {
for (var i = 0; i < children.length; i++) {
if (children[i].tag) {
html.push('<' + tag + '>');
if (children[i].children) {
loop();
}
html.push('</' + tag + '>');
return html;
} else {
throw '[JHTML] Bad syntax: Tag type is not defined on node.';
}
}
};
}).inject();
JHTML.addComponent('/generate:init', function(jsonInput, process) {
console.log(process);
var html = process(jsonInput);
return html;
}).inject([null, '/generate:process']);
JHTML.addHook('generate', function(jsonInput, init) {
var html = init(jsonInput);
return html;
}).inject([null, '/generate:init']);
handle = JHTML.returnUserHandle();
/* HTML Generator Syntax - Client */
var htmlChunk = [{
tag: '!DOCTYPEHTML'
}, {
tag: 'html',
children: [{
tag: 'head',
children: []
}, {
tag: 'body',
children: []
}]
}];
console.log(handle.generate(htmlChunk));
&#13;
答案 0 :(得分:0)
是我试图实现不可能的语法吗?
这绝对是可能的,而且我确信它有一些错误修正,它可以正常工作。
您所描述的内容与Asynchronous Module Definition (AMD)基本相同,后者广泛用于处理代码依赖性。
我建议您尝试使用requirejs并遵循现有标准,而不是继续追求自己版本的相同概念。