无论如何在 Visual Studio 智能感知中定义一个未定义的对象?

Posted

技术标签:

【中文标题】无论如何在 Visual Studio 智能感知中定义一个未定义的对象?【英文标题】:Is there anyway to define an undefined object in Visual Studio intellisense? 【发布时间】:2013-10-31 14:59:15 【问题描述】:

假设我在 AngularJS 中有一个控制器:

myApp.controller('SearchController',
    function ($scope, UserService) 

        // for intellisense, UserService is undefined here
        var user = UserService.getUsers().then(function(data)
                             // yada yada
                   , function(err)
                             // yada yada
                   );
    );

但是,在我的智能感知文件中,我可以动态注入 UserService 来获得它的功能,如下所示:

intellisense.addEventListener('statementcompletion', function (event) 
    // tried doing this, but doesn't work!
    // event.target   = ;

    var injector   = angular.injector(['ng', 'myApp']);
    var dependency = injector.get(event.targetName);

    event.items    = [];
    for (method in dependency) 
        intellisense.logMessage(method);
        event.items.push( name: method, kind: 'field', value: function ()   );
    

);

现在,如果我有一个定义为UserService = 的全局变量(或函数变量),并且在我的控制器函数中输入UserService.,我将弹出服务中的所有函数。但是如果我没有定义它,因为它被智能感知解释为undefined,即使statementcompletion 正在工作(如在javascript语言服务控制台中看到的那样),它也无法向我显示选项。

我的问题是,除了注释函数之外,还有没有将UserService 定义为智能感知文件中的对象?定义 event.target = 不起作用(参见上面的智能感知代码)。

【问题讨论】:

我现在使用的后备技巧是将我的对象设置为一个空值(如果尚未设置),那么我就有一个可以在智能感知中使用的目标。在上面的示例中,我将只包含 $scope = $scope || ;在我的职能开始时。这是一个 hack,但确实有效。 我想过这样做,但它会弄乱源代码,这是不可取的。相反,我所做的是“调用”角度组件(如控制器、服务..等),它们基本上是带有智能感知代码中的空对象的函数。瞧,你有你想要的所有智能感知! 你是怎么做到的?有代码示例可以指点我吗? 查看答案。 【参考方案1】:

一种可行的方法是使用空对象从智能感知代码中“调用”组件功能(控制器、服务等)。

我相信这会更干净,但这是我所做的:

https://github.com/diwasbhattarai/angularjs-intellisense

约翰·布莱索: https://github.com/jmbledsoe/angularjs-visualstudio-intellisense/

references.js - 在 Tools>Options>TextEditor>Javascript>Intellisense>References 中添加此文件作为参考

    /// <reference path="../source/lib/assetBundle.js" />
    /// <reference path="_moduleDecorator.js" />
    /// <reference path="_componentDecorator.js" />
    /// <reference path="../source/app/appBundle.js" />

    intellisense.addEventListener('statementcompletion', function (event) 
    // for core angular objects
    addComponentToIntellisense('ng');
    // for custom objects in application modules
    for (var moduleIndex in modules) 
        addComponentToIntellisense(modules[moduleIndex]);
    

    function addComponentToIntellisense(module) 
        var $injector = angular.injector(['ng', module]),
            dependency = $injector.get(event.targetName),
            dep;

        if (typeof dependency === "function") dep = new dependency();
        else dep = dependency;

        for (var method in dep) 
            event.items.push( name: method, kind: 'field', value: dependency[method] );
        
    
);

_moduleDecorator.js - 跟踪应用中的所有模块

    //_moduleDecorator
    (function () 
    var originalModule = angular.module;
    // TODO change to array
    modules = ;
    var rep = false;
    var count = 0;
    angular.module = function () 
        for (var k in modules) 
            if (modules[k] === arguments[0]) 
                rep = true;
                break;
            
        
        if (!rep) modules[count++] = arguments[0];

        return originalModule.apply(angular, arguments);
    ;
)();

_componentDecorator.js - 以空对象参数“调用”组件函数

    (function () 
    // pick all the components in all modules and initialize them for intellisense
    for (var moduleIndex in modules) 
        var currentModule = angular.module(modules[moduleIndex]),
            queue = currentModule._invokeQueue,
            // add other components such as value, provider, etc later
            angularComponents = ['controller', 'factory', 'service', 'value'];

        for (var i = 0; i < angularComponents.length; i++) 
            var currentComponent    = angularComponents[i],
                originalComponentFn = currentModule[currentComponent];

            currentModule[currentComponent] = (function (currentModule, queue, originalComponentFn) 
                return function () 
                    originalComponentFn.apply(currentModule, arguments);
                    initializeComponents(queue);
                ;
            )(currentModule, queue, originalComponentFn);
        
    

    function initializeComponents(queue) 
        var elem = queue.filter(function (element) 
            var componentName = element[2][0].toLowerCase();
            return (componentName.indexOf(componentName) !== -1);
        );

        for (var i = 0; i < elem.length; i++) 
            var tempComp = elem[i][2][1],
                compFunc;

            // for array notation for DI
            if (typeof tempComp !== "function") 
                compFunc = tempComp[tempComp.length - 1];
             else 
                compFunc = tempComp;
            

            // 10 parameter dependencies initialization for now
            compFunc(, , , , , , , , , );
        
    
)();

【讨论】:

这让我大开眼界!非常感谢您发布这个。我正在考虑将我的实现打包到(MIT 许可的)GitHub 存储库中,但希望您允许合并其中的一些位。我对它进行了相当大的修改,在未找到精确匹配时执行模糊匹配,允许提供程序注入等等。我只需要这个位来初始化带有空参数的函数。 没问题。你可以继续打包它。很高兴它帮助了你:) 哦,你能把 repo 贴在这里让我看看吗? 当然。可能是这个周末,但也可能更晚,具体取决于。 我真的很想把它加入到 Web Essentials for Angular 特定的 Intellisense 中。如果您有兴趣分享,请告诉我

以上是关于无论如何在 Visual Studio 智能感知中定义一个未定义的对象?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript AMD 模块:如何跨模块获取 Visual Studio 智能感知

如何在 Visual Studio 2017 for Unity 中启用智能感知 [重复]

如何在 Visual Studio Code 中为 Unity 函数名称获取智能感知?

Visual Studio 中的原型/Scriptaculous 智能感知

Visual Studio 中的 Jquery 没有智能感知

Visual Studio Code 显示智能感知一行?