我们目前正在迁移到Google Closure Compiler。我们重构了旧的代码库,因此它符合本文:A radical new approach to developing AngularJS apps
指令应如下所示:
/**
* @constructor
*/
var Directive = function(version) {
this.version = version;
this.link = this.link.bind(this);
this.scope;
this.elem;
this.attrs;
};
/**
* Version directive factory. Entry point and used in `module.directive`.
*/
Directive.factory = function(version) {
var dir = new Directive(version);
return {
link: dir.link
};
};
/**
* Linking function.
*/
Directive.prototype.link = function(scope, elem, attrs) {
this.scope = scope;
this.elem = elem;
this.attrs = attrs;
this.elem.text(this.version.get());
};
angular.module('app', [])
.directive('version', Directive.factory);
一切正常,直到我们在网站上多次使用指令。 Directive.factory
只会被调用一次。因此,站点上的所有指令共享相同的Directive对象。我们不明白,为什么会这样。
答案 0 :(得分:2)
An Angular service is a singleton object created by a service factory。所以DDO个对象是,它们是单个数组,它们是由directive factory functions返回的对象创建的(指令似乎是引擎盖下的服务)。一旦调用了工厂函数(在您的情况下为Directive.factory
),其结果将缓存为versionDirective
服务实例。
一旦你知道Angular treats compile
and link
functions究竟是如何完成的,就可以通过这样的伎俩:
Directive.factory = function(version) {
return {
compile: function () {
var dir = new Directive(version);
// by default there is no 'this' in link
return angular.bind(dir, dir.link);
}
};
};
除非你知道你做得很好,否则我会反对它。它不会有助于测试性,可维护性,或任何会滥用框架的东西。
“彻底的新方法”可能会或可能不会有益,但它肯定不会暗示这样的事情。
答案 1 :(得分:1)
我改变了你的例子,以反映指令构造函数是一个共享的单例。
/**
* @constructor
*/
var Directive = function(version) {
this.version = version;
};
/**
* Version directive factory. Entry point and used in `module.directive`.
*/
Directive.factory = function(version) {
return new Directive(version);
};
/**
* Linking function.
*/
Directive.prototype.link = function(scope, elem, attrs) {
// this refers to the Directive singleton - it's shared between
// multiple invocations.
elem.text(this.version.get());
};
angular.module('app', [])
.directive('version', Directive.factory);
如果您想要最初的目标,可以改变链接方法来构建对象:
/**
* Linking function.
*/
Directive.prototype.link = function(scope, elem, attrs) {
// This will be created everytime the template is cloned
var versionDirective = new VersionDirectiveLink(scope, elem, attrs);
versionDirective.setText(this.version.get());
};
后一种变体每次克隆模板时都会创建一个对象。您可以通过这种方式支持构造函数的更高级行为。