你如何通过工厂 create/compile 指令?
How do you create/compile a directive via a factory?
我正在建造一个 Modal 工厂,并且经常被 $compile
的问题难倒。我正在尝试使用工厂将 Modal 指令动态添加到页面。
指令本身有一些内部逻辑,允许它通过 API 服务发布来打开。它在 postLink
中将自己注册到 pub/sub 服务,如下所示:
postLink: function(scope, element, attrs) {
api.subscribe(attrs.id, function(msg) {
//magic happens here
});
}
工厂像这样创建并附加指令:
angular.module('modal')
.factory('ModalFactory', ['$compile', '$rootScope', 'Api', function($compile, $rootScope, api) {
return function modalFactory(config) {
var scope, element, html, id;
init(); //run init so it's initialized on creation
function activate() {
api.publish(id, 'activate');
}
function init() {
//checks if initialized already
//uses assembleDirective to get the html string and scope
angular.element(document.body).append($compile(html)(scope)); //this is the important line of code
}
function assembleDirective() {
//an html string is assembled here and stored into html. uses html from config
//rootscope is used to create a new scope (unless provided in config)
}
return {
activate: activate,
deactivate: deactivate
}
}
}]);
这是问题所在,每当我在控制器中 运行 这个逻辑时,就像这样:
//imagine we're in a controller
var myModal = new ModalFactory({ }); //create empty modal
myModal.activate(); //fails
问题?当我 运行 myModal.activate()
时,出于某种原因,指令还没有 运行 任何内部 linking 逻辑。我 console.logged 在指令本身 运行s link 之前 运行s 列出了过程和激活方法。这让我大吃一惊,因为我以为我刚刚编译它并添加到 DOM(当我想到编译时,我想到了 pre/post link 函数 运行宁)
当我在控制台记录 $compile(html)(scope)
时,它 returns 一个编译了 everything 的 jQLite 元素,这让我认为它工作正常。但是,当我从 jQLite 对象中得到 DOM 的实际部分时(通过在最后执行 [0]
),我得到了原始 HTML 的 DOM 表示字符串,未编译。
当我将一个单独的方法附加到点击时 运行s myModal.activate()
的控制器时,指令已经 运行 它的 link 方法并且模态被激活.
我相信你的问题是在 DOM 周围移动 angular 元素与 Angulars 内部构件。做你正在做的事情的安全方法是先附加它,然后编译。两者之间的时间间隔将很小。如果您这样更改代码,您会遇到问题吗?
function init() {
//checks if initialized already
//uses assembleDirective to get the html string and scope
var modalElt = angular.element(document.body).append(html);
$compile(modalElt)(scope);
}
也许可以查看 Brian Ford 的 angular-modal 中的代码:
https://github.com/btford/angular-modal/blob/master/modal.js
寻找带有 $compile
的行
对于仔细阅读这个问题的任何人,我终于想出了一个答案,首先彼得的建议帮助很大(在追加元素后编译)。
我最后做的是在编译前在作用域上设置一个 属性。 属性 在 postLink 的模态中触发了一个 init
函数,因此 $compile
的异步性质最终并不重要。
我正在建造一个 Modal 工厂,并且经常被 $compile
的问题难倒。我正在尝试使用工厂将 Modal 指令动态添加到页面。
指令本身有一些内部逻辑,允许它通过 API 服务发布来打开。它在 postLink
中将自己注册到 pub/sub 服务,如下所示:
postLink: function(scope, element, attrs) {
api.subscribe(attrs.id, function(msg) {
//magic happens here
});
}
工厂像这样创建并附加指令:
angular.module('modal')
.factory('ModalFactory', ['$compile', '$rootScope', 'Api', function($compile, $rootScope, api) {
return function modalFactory(config) {
var scope, element, html, id;
init(); //run init so it's initialized on creation
function activate() {
api.publish(id, 'activate');
}
function init() {
//checks if initialized already
//uses assembleDirective to get the html string and scope
angular.element(document.body).append($compile(html)(scope)); //this is the important line of code
}
function assembleDirective() {
//an html string is assembled here and stored into html. uses html from config
//rootscope is used to create a new scope (unless provided in config)
}
return {
activate: activate,
deactivate: deactivate
}
}
}]);
这是问题所在,每当我在控制器中 运行 这个逻辑时,就像这样:
//imagine we're in a controller
var myModal = new ModalFactory({ }); //create empty modal
myModal.activate(); //fails
问题?当我 运行 myModal.activate()
时,出于某种原因,指令还没有 运行 任何内部 linking 逻辑。我 console.logged 在指令本身 运行s link 之前 运行s 列出了过程和激活方法。这让我大吃一惊,因为我以为我刚刚编译它并添加到 DOM(当我想到编译时,我想到了 pre/post link 函数 运行宁)
当我在控制台记录 $compile(html)(scope)
时,它 returns 一个编译了 everything 的 jQLite 元素,这让我认为它工作正常。但是,当我从 jQLite 对象中得到 DOM 的实际部分时(通过在最后执行 [0]
),我得到了原始 HTML 的 DOM 表示字符串,未编译。
当我将一个单独的方法附加到点击时 运行s myModal.activate()
的控制器时,指令已经 运行 它的 link 方法并且模态被激活.
我相信你的问题是在 DOM 周围移动 angular 元素与 Angulars 内部构件。做你正在做的事情的安全方法是先附加它,然后编译。两者之间的时间间隔将很小。如果您这样更改代码,您会遇到问题吗?
function init() {
//checks if initialized already
//uses assembleDirective to get the html string and scope
var modalElt = angular.element(document.body).append(html);
$compile(modalElt)(scope);
}
也许可以查看 Brian Ford 的 angular-modal 中的代码:
https://github.com/btford/angular-modal/blob/master/modal.js
寻找带有 $compile
的行对于仔细阅读这个问题的任何人,我终于想出了一个答案,首先彼得的建议帮助很大(在追加元素后编译)。
我最后做的是在编译前在作用域上设置一个 属性。 属性 在 postLink 的模态中触发了一个 init
函数,因此 $compile
的异步性质最终并不重要。