我不确定之前是否曾经问过这个问题,但是我经历了很多有角度的双向约束帖,坦率地说不清楚他们在谈论什么。所以我再说一次我的问题。
假设我想使用标签输入插件,例如this。我定义了一个名为tags的角度指令,并在其中初始化文本输入上的tagsinput。 text元素绑定到一个模型,该模型在服务器中填充在控制器中。
我在Plunker here.
中有这个问题是当指令加载时,模型尚未填充,因此tagsinput插件初始化为空值。但是我想用服务器端值初始化它。我经常遇到这个问题,并且我一直在控制器中使用服务器回调来初始化我的插件,我知道这是主要的罪恶。
我无法忘记最终,在某种程度上,插件初始化必须延迟,直到服务返回,因此值可用。如果我说即使采取有角度的方式,这是以某种方式实现的,我是否正确?但无论如何,我无法弄清楚如何使其发挥作用。
答案 0 :(得分:2)
我认为解决此问题的最佳方法是在指令中使用观察程序。
var app = angular.module('app', []);
app.controller('Main', function ($scope, $timeout) {
//this simulates data being loaded asynchronously after 3 second
$timeout(function () {
$scope.list = [1, 2, 3, 4];
}, 3000);
});
app.directive("mydirective", function()
{
return {
restrict: "A",
link: function(scope, element, attrs)
{
scope.$watch('list', function (newVal, oldVal) {
if (newVal) {
//initialize the plugns etc
scope.result = 'Model has been populated';
}
});
}
};
});
在我的示例中,我在控制器内使用$ timeout来模拟异步数据加载,一旦'list'模型被填充,指令内的观察者将实现它(newVal不为空或未定义)然后插件可以初始化。这是一种更好的方法,而不是控制器内部的回调,因为你的代码更加简洁。
这是jsBin
编辑:
请记住,填充模型时必须触发摘要周期。如果您使用$ resource或$ http从服务器获取数据,则不必担心,但如果您在Angular之外进行操作,则必须使用$ scope激活摘要周期。$ apply()所以观察者可以意识到该模型已填充。
答案 1 :(得分:1)
正如Bertrand所说,通过在指令link
函数中使用观察者可以实现这一点。您需要等待数据出现,这就是观察者的目的。在http://plnkr.co/edit/hb3UYl查看我对您的plunker的更新。
我使用$timeout
而不是$http
伪造了异步响应,但这并不重要。
它的作用是在指令的链接函数中设置观察者,该函数寻找$scope.list
的变化。如果检测到更改并且newValue
是有用的,则使用它来填充输入字段并将其转换为标记列表。
注意我已将$('.taginput')
更改为element
,因为这是您正在操作的内容。此外,我认为这是一种很好的做法,只能在当前element
的层次结构中搜索您想要操作的DOM元素。这使您确信如果将指令放在给定元素上 - 除此之外的其他元素及其子元素都不会受到影响。