当我使用 angular.module(...).controller(...).directive(...) 时会发生什么?为什么?
What happens when I use angular.module(...).controller(...).directive(...)?And why?
我认为这等于
var module = angular.module(...);
module.controller(...);
module.directive(...);
但我不确定。而且我不知道 angular 中发生了什么,也不知道为什么我可以这样写代码。
我尝试调试和跟踪它,但它很混乱。
What happens when I use angular.module(…).controller(…).directive(…)?And why?
简答
这是在一个文件中编写代码的好方法。
如果要将 Angular 项目拆分为不同的文件,请使用第二种方法:
var app = angular.module(...);
app.controller(...);
app.directive(...);
长答案
另请查看此 angular 代码片段(摘自 https://code.angularjs.org/1.5.6/angular.js):
可以看到controller
、directive
、module
、filter
、factory
、value
、provider
、 decorator
, animation
, config
, component
,run
returns moduleInstance
function setupModuleLoader(window) {
var $injectorMinErr = minErr('$injector');
var ngMinErr = minErr('ng');
function ensure(obj, name, factory) {
return obj[name] || (obj[name] = factory());
}
var angular = ensure(window, 'angular', Object);
// We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
angular.$$minErr = angular.$$minErr || minErr;
return ensure(angular, 'module', function() {
/** @type {Object.<string, angular.Module>} */
var modules = {};
return function module(name, requires, configFn) {
var assertNotHasOwnProperty = function(name, context) {
if (name === 'hasOwnProperty') {
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
}
};
assertNotHasOwnProperty(name, 'module');
if (requires && modules.hasOwnProperty(name)) {
modules[name] = null;
}
return ensure(modules, name, function() {
if (!requires) {
throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
"the module name or forgot to load it. If registering a module ensure that you " +
"specify the dependencies as the second argument.", name);
}
/** @type {!Array.<Array.<*>>} */
var invokeQueue = [];
/** @type {!Array.<Function>} */
var configBlocks = [];
/** @type {!Array.<Function>} */
var runBlocks = [];
var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
/** @type {angular.Module} */
var moduleInstance = {
// Private state
_invokeQueue: invokeQueue,
_configBlocks: configBlocks,
_runBlocks: runBlocks,
requires: requires,
name: name,
provider: invokeLaterAndSetModuleName('$provide', 'provider'),
factory: invokeLaterAndSetModuleName('$provide', 'factory'),
service: invokeLaterAndSetModuleName('$provide', 'service'),
value: invokeLater('$provide', 'value'),
constant: invokeLater('$provide', 'constant', 'unshift'),
decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
config: config,
run: function(block) {
runBlocks.push(block);
return this;
}
};
if (configFn) {
config(configFn);
}
return moduleInstance;
function invokeLater(provider, method, insertMethod, queue) {
if (!queue) queue = invokeQueue;
return function() {
queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};
}
function invokeLaterAndSetModuleName(provider, method) {
return function(recipeName, factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
invokeQueue.push([provider, method, arguments]);
return moduleInstance;
};
}
});
};
});
}
Why is it better?
两种方法的作用相同,因此开发人员将决定哪种方法更适合他的项目结构
for efficiency?
没有效率值测量,两者具有相同的效率。没有性能损失。
for what?
在项目中我想在单独的文件中编写每个指令每个控制器...所以我使用 app.controller(...);
, app.service(...);
,...
但是 common 指令我想放在一个文件中所以我使用:
app.directive(…).directive(…).directive(…).directive(…).directive(…)
希望它能对您的理解有所启发 :)
这才叫一口流利API。
每个方法都会return模块实例,以便可以调用另一个方法。
为了说明,我们可以创建一个执行类似操作的 class。
class Module {
controller() {
console.log('controller');
return this;
}
directive() {
console.log('directive');
return this;
}
}
每个方法完成后,它将 return 模块实例 this
以便可以链接另一个方法。
所以现在我们可以使用这个 class 并像这样链接方法:
new Module().controller().directive();
或
const module = new Module();
module.controller();
module.directive();
我认为这等于
var module = angular.module(...);
module.controller(...);
module.directive(...);
但我不确定。而且我不知道 angular 中发生了什么,也不知道为什么我可以这样写代码。
我尝试调试和跟踪它,但它很混乱。
What happens when I use angular.module(…).controller(…).directive(…)?And why?
简答
这是在一个文件中编写代码的好方法。
如果要将 Angular 项目拆分为不同的文件,请使用第二种方法:
var app = angular.module(...);
app.controller(...);
app.directive(...);
长答案
另请查看此 angular 代码片段(摘自 https://code.angularjs.org/1.5.6/angular.js):
可以看到controller
、directive
、module
、filter
、factory
、value
、provider
、 decorator
, animation
, config
, component
,run
returns moduleInstance
function setupModuleLoader(window) {
var $injectorMinErr = minErr('$injector');
var ngMinErr = minErr('ng');
function ensure(obj, name, factory) {
return obj[name] || (obj[name] = factory());
}
var angular = ensure(window, 'angular', Object);
// We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
angular.$$minErr = angular.$$minErr || minErr;
return ensure(angular, 'module', function() {
/** @type {Object.<string, angular.Module>} */
var modules = {};
return function module(name, requires, configFn) {
var assertNotHasOwnProperty = function(name, context) {
if (name === 'hasOwnProperty') {
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
}
};
assertNotHasOwnProperty(name, 'module');
if (requires && modules.hasOwnProperty(name)) {
modules[name] = null;
}
return ensure(modules, name, function() {
if (!requires) {
throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
"the module name or forgot to load it. If registering a module ensure that you " +
"specify the dependencies as the second argument.", name);
}
/** @type {!Array.<Array.<*>>} */
var invokeQueue = [];
/** @type {!Array.<Function>} */
var configBlocks = [];
/** @type {!Array.<Function>} */
var runBlocks = [];
var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
/** @type {angular.Module} */
var moduleInstance = {
// Private state
_invokeQueue: invokeQueue,
_configBlocks: configBlocks,
_runBlocks: runBlocks,
requires: requires,
name: name,
provider: invokeLaterAndSetModuleName('$provide', 'provider'),
factory: invokeLaterAndSetModuleName('$provide', 'factory'),
service: invokeLaterAndSetModuleName('$provide', 'service'),
value: invokeLater('$provide', 'value'),
constant: invokeLater('$provide', 'constant', 'unshift'),
decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
config: config,
run: function(block) {
runBlocks.push(block);
return this;
}
};
if (configFn) {
config(configFn);
}
return moduleInstance;
function invokeLater(provider, method, insertMethod, queue) {
if (!queue) queue = invokeQueue;
return function() {
queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};
}
function invokeLaterAndSetModuleName(provider, method) {
return function(recipeName, factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
invokeQueue.push([provider, method, arguments]);
return moduleInstance;
};
}
});
};
});
}
Why is it better?
两种方法的作用相同,因此开发人员将决定哪种方法更适合他的项目结构
for efficiency?
没有效率值测量,两者具有相同的效率。没有性能损失。
for what?
在项目中我想在单独的文件中编写每个指令每个控制器...所以我使用 app.controller(...);
, app.service(...);
,...
但是 common 指令我想放在一个文件中所以我使用:
app.directive(…).directive(…).directive(…).directive(…).directive(…)
希望它能对您的理解有所启发 :)
这才叫一口流利API。
每个方法都会return模块实例,以便可以调用另一个方法。
为了说明,我们可以创建一个执行类似操作的 class。
class Module {
controller() {
console.log('controller');
return this;
}
directive() {
console.log('directive');
return this;
}
}
每个方法完成后,它将 return 模块实例 this
以便可以链接另一个方法。
所以现在我们可以使用这个 class 并像这样链接方法:
new Module().controller().directive();
或
const module = new Module();
module.controller();
module.directive();