我正在尝试关注this SO answer explaining how to render a recursive JSON structure using a directive。但是,与提供的答案不同,当加载DOM并且Angular第一次运行时,我的数据不已知。
相反,我的数据从HTML输入字段中检索并存储在Angular服务中(当用户提交表单时)。
如何在修改服务数据时保持Angular Directive的最新状态?
回复时更新
@musically_ut提供了一个很好的答案,但却揭示了一个相关问题,阻止了实施(在此更新)。
指令呈现包含Angular {{expressions}}
的HTML,其访问存储在$scope
中的数据。由于服务已准备好数据,原始解决方案为$watch
。在 指令呈现之前,如何确保将“新”数据添加到$scope
?
架构和流程概述如下:
ControllerA
- >获取用户的意见ControllerA
- >使用服务转换数据ControllerB
- > {strong} $watch
Directive
- > {strong} $watch
ControllerB
- >将数据添加到$scope
Directive
- >使用显示转换后的数据(来自服务)
指令 问题出在第5步和第6步之间。指令在ControllerB将数据添加到{{expressions}}
之前呈现$scope
。即使这确实有效,但感觉太复杂和“黑客”。
事实上,为了回归,我在ControllerB中使用$watch
来监听转换后的数据何时在服务中准备就绪。即使这感觉有点矫枉过正(服务没有异步调用)。
答案 0 :(得分:17)
您可以在定义指令时注入服务,然后在数据上设置$watch
。所以在你的情况下:
.directive('tree', function ($compile, myService) {
return {
// ...
link: function (scope, element, attrs) {
scope.$watch(function () {
return myService.getData();
},
function (newVal) {
if (typeof newVal !== 'undefined') {
// ...
}
}
});
}
});
这将观察要更改的数据,并在每次数据更改时运行代码。
但是,如果数据在设置一次后没有改变,更好的方法(更有效)是从服务返回一个promise($http
方法直接返回一个promise或者您可以使用$q
服务创建一个),然后将您的计算添加为数据的延续。
.directive('tree', function ($compile, myService) {
return {
// ...
link: function (scope, element, attrs) {
myService.getData().then(function (data) {
// ...
}, function (err) {
// Handle error
});
}
}
});
答案 1 :(得分:0)
我编写了一个简短的函数,可以将数据放入Object而无需替换它。 您可以在服务中使用它。这样你就不需要使用手表了。您可以使用Angular的正常摘要循环。 例如,看到这个简单的控制器&服务:
演示:JSFidde - http://jsfiddle.net/y09kx7f7/1/ 断言测试
<强>控制器:强>
app.controller('dem',function($scope,me){
$scope.user=me.user; // {name:'user name'}
})
每次更改用户名时,控制器将自动进行无人值守!
<强>服务强>
.factory('me',function($timeout){
var obj={}
obj.user={name:'hello'}
$timeout(function(){ //Example of change the data
newUser={name:'israel'}
cloneInto(obj.user,newUser)
},1000)
return obj
})
我写的cloneInto函数:
// The function it is like a=b,
// but keeping the object in his original memory position.
function cloneInto(a,b){
var i
for (i in a){
if(typeof a[i]!='object') //For supporting deep-copy
delete a[i]
}
for (i in b){
if (typeof b[i]=='object'){
if(!a[i]) a[i]={}
cloneInto(a[i],b[i])
}
else{
a[i]=b[i]
}
}
}