这是" DI"结构不可能,或者我应该找一个bug?

时间:2015-12-09 18:17:14

标签: javascript dependency-injection

说明:

作为一个个人项目,我试图创建自己的轻量级版本的依赖注入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;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

  

是我试图实现不可能的语法吗?

这绝对是可能的,而且我确信它有一些错误修正,它可以正常工作。

您所描述的内容与Asynchronous Module Definition (AMD)基本相同,后者广泛用于处理代码依赖性。

我建议您尝试使用requirejs并遵循现有标准,而不是继续追求自己版本的相同概念。