我是Angular的新手,并且正在使用包含一些现有JavaScript代码的应用。在循环内部,app会附加文件输入按钮,这些按钮会添加到视图中的表行中,如下所示:
cellSeq.innerHTML = cellSeq.innerHTML +
'<input type="file" name="f" multiple="multiple" file-bind="" id="my-files-input-' +
counter + '">';
因此,通过将counter
变量添加到其ID,每个表行上的按钮都是唯一的。我有一个名为file-bind
的文件读取指令,我可以附加到一个按钮(没有counter
),它处理输入读取的文件。
在测试中,这适用于单个按钮,我只是手动粘贴到HTML中(其ID上没有计数器变量):
<input type="file" name="f" multiple="multiple" file-bind="" />
这里是文件阅读指令签名(不太令人兴奋):
angular.module('myApp').directive('fileBind', function() {
'use strict';
return function(scope, element, attrs) {
element.bind('change', function(evt) {
// ...read files
我怀疑问题与我创建指令的方式有关。我想要做的是将我的file-bind指令绑定到每个这些独特的按钮,并在读取文件后更新视图的相应部分。
如何为每个按钮添加一个唯一的指令(就执行上下文而言)?
编辑似乎我需要一个compile
函数,因为重复元素是在纯JavaScript中创建的。我在哪里放置编译函数,假设我的指令返回一个函数(而不是一个对象,我可以放置&#39; compile:function()...&#39;)?
答案 0 :(得分:1)
当使用jQuery以编程方式向DOM添加新的html而不是使用angular(通过ng-repeat,ng-if等)添加它时,Angular很幸福地发现任何事情都发生了变化并且需要相应地做出响应。
因此,您需要在新添加的HTML上调用$ compile以警告Angular它需要重新解析模板并正确编译和链接任何找到的指令。
为了做到这一点,你需要将要编译的元素和元素的范围都传递给$compile()
。
cellSeq.innerHTML = cellSeq.innerHTML +
'<input type="file" name="f" multiple="multiple" file-bind="" id="my-files-input-' +
counter + '">';
var element = angular.element(cellSeq);
var scope = element.scope();
$compile(element.contents())(scope);
以上假设您在可以注入$compile
(角度控制器)的上下文中使用jQuery。但是,这很可能不是您的用例。如果您要在外部托管组件(例如插件)中通过jQuery添加html,则必须获得更多创意,因为您必须检索$injector
实例,以便可以访问$compile
。
var outerEl = document.getElementById('outer');
outerEl.innerHTML = counter + '<input type="file" name="f"
multiple="multiple" file-bind="" id="my-files-input-' +
counter + '">';
var element = angular.element(outerEl);
var scope = element.scope();
// retrieve the default injector instance
var $injector = angular.injector(['ng']);
$injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) {
var $scope = scope || $rootScope;
$compile(element.contents())($scope);
$scope.$digest();
}]);
你可以看到这个plunkr
如果您的元素不包含范围,则您需要冒泡到$rootScope
,因为您必须有$compile
的范围才能运行。
我们需要在这个场景中编译后调用$scope.$digest()
,因为我们在正常的摘要周期之外从jQuery调用$compile
。因此,如果未调用$digest
,则无法正确刷新模型绑定。
正如您所看到的,这只是添加一些HTML的很多复杂功能!最好的方法是始终在一个角色中思考。尽可能使用适当的角度工具,指令来管理DOM操作。