admin管理员组

文章数量:1278915

Lets say I have a controller in 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
                   });
    });

However, in my intellisense file, I can dynamically inject UserService to get its functions like this:

intellisense.addEventListener('statementpletion', 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 () { } });
    }

});

Now, if I have a global variable (or function variable) defined as UserService = {} and inside my controller function I type UserService. I will get a pop up of all the functions in the service. But if I don't have it defined, since it is interpreted as undefined by intellisense, it can't show me the options even though statementpletion is working (as seen in the Javascript Language Service console).

My question is, apart from annotating the function, is there anyway to define UserService as an object in the intellisense file? Defining event.target = {} does not work (see intellisense code above).

Lets say I have a controller in 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
                   });
    });

However, in my intellisense file, I can dynamically inject UserService to get its functions like this:

intellisense.addEventListener('statementpletion', 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 () { } });
    }

});

Now, if I have a global variable (or function variable) defined as UserService = {} and inside my controller function I type UserService. I will get a pop up of all the functions in the service. But if I don't have it defined, since it is interpreted as undefined by intellisense, it can't show me the options even though statementpletion is working (as seen in the Javascript Language Service console).

My question is, apart from annotating the function, is there anyway to define UserService as an object in the intellisense file? Defining event.target = {} does not work (see intellisense code above).

Share Improve this question asked Oct 22, 2013 at 16:07 javaCityjavaCity 4,3182 gold badges27 silver badges37 bronze badges 3
  • The fallback hack that I'm using at this point is to set my object to an empty value if not already set, then I have a target to work with in intellisense. In the above example I would just include $scope = $scope || {}; at the beginning of my function. It's a hack but does work. – John Bledsoe Commented Mar 7, 2014 at 15:16
  • I thought about doing that but it would mess up with the source code, which is not desirable. What I did instead was to "call" the angular ponents (like controller, service..etc), which are basically functions with empty objects from intellisense code. Voila, you have all the intellisense you want! – javaCity Commented Mar 7, 2014 at 16:00
  • How exactly do you do that? Is there a code sample you can point me to? – John Bledsoe Commented Mar 7, 2014 at 16:12
Add a ment  | 

1 Answer 1

Reset to default 13 +200

One way that works is to "call" the ponent functions (controller, services, etc) from intellisense code with empty objects.

I am sure this can be a lot cleaner but here's what I've done:

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

By John Bledsoe: https://github./jmbledsoe/angularjs-visualstudio-intellisense/

references.js - add this file as reference in Tools>Options>TextEditor>Javascript>Intellisense>References

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

    intellisense.addEventListener('statementpletion', 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 - to keep track of all the modules in your app

    //_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);
    };
})();

_ponentDecorator.js - to "call" ponent functions with empty object parameter

    (function () {
    // pick all the ponents in all modules and initialize them for intellisense
    for (var moduleIndex in modules) {
        var currentModule = angular.module(modules[moduleIndex]),
            queue = currentModule._invokeQueue,
            // add other ponents 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 ponentName = element[2][0].toLowerCase();
            return (ponentName.indexOf(ponentName) !== -1);
        });

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

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

            // 10 parameter dependencies initialization for now
            pFunc({}, {}, {}, {}, {}, {}, {}, {}, {}, {});
        }
    }
})();

本文标签: javascriptIs there anyway to define an undefined object in Visual Studio intellisenseStack Overflow