我正在研究一个使用REST后端为AngularJS前端提供JSON的项目组合项目。下面是我发送的JSON对象的示例,其格式是为了便于阅读。
"fields":
{
"description": "This is a test tree for JSON serialization",
"name": "Test tree 1",
"techniques": [1,2]
},
"pk": 1,
"model": "dominion.tree"
我处于Angular的新手级别,因此我遇到了试图显示附加到此树的技术的问题。
目前,我有一个名为tree的指令,它将提取JSON数据并使其可供使用和显示。嵌套在其中,我有一个ng-repeat,它遍历树中的每个技术id,并调用一个技术指令,该指令将id作为参数从数据库中提取该技术。
tree.html
<trees>
<div ng-repeat="pk in jsonstuff">
{{pk.fields.name}}
<div ng-repeat="technique in pk.fields.techniques">
<technique idnum='{{technique}}'>
{{techniqueJSON}}
</technique>
</div>
</div>
</trees>
技术指令
.directive("technique", function(){
return{
scope: {id: '@idnum'},
transclude: 'true',
controller: function($scope, $http, $attrs) {
techniqueJSON = {}
urlstuff = 'http://localhost:8000/dominion/api/techniques/' + $scope.id
$http.get(urlstuff).
success(function(data, status, headers, config) {
techniqueJSON = data
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
},
controllerAs: 'techniqueCtrl',
template: '<ng-transclude></ng-transclude>'}
})
我不想在模板中使用技术JSON信息,因为根据应用程序中该指令的位置,它可以显示不同的数据子集。我的解决方案是尝试在指令标记的HTML内部的绑定中访问techniqueJSON对象。
这似乎不起作用,我相信这是因为{{technique}}绑定需要的隔离范围才能正确评估,而不是设置为undefined或字面上作为/ dominion传递/ API /技术/ {{技术}}
自上而下,我的问题如下:
只是从REST API角度引用树中技术的主键是正确的决定,还是应该在请求树时将技术信息与树一起序列化?
是否有更好的方法从Angular方面调用此信息,而不是使用单独的指令? (即为树内的技术调用循环$ http.get()($ http.get)
有没有更好的方法在单独的指令之间传递ID号,这意味着我可以避免使用隔离范围?
感谢您的时间。
答案 0 :(得分:1)
查看此工作演示:JSFiddle。好吧,我在演示中使用user
作为模型对象。
创建工厂UserFactory
并展示两个函数ids
和user
。任何想要获取用户数据的指令/控制器都可以注入此工厂并调用API。
我还更正了代码中的一些错误,例如techniqueJSON = {}
应为$scope.techniqueJSON = {}
。
注意:我使用JSONPlaceholder来模拟
$http
来电。
是。每个项目的显示应由technique
指令独立控制。
我总是建议将data fetching
逻辑提取到service
/ factory
。这更容易维护。此外,可以跨不同的控制器/指令缓存和重用数据。
此类factory
用作前端的model base
。
使用隔离范围很好。隔离范围的强大之处在于使您的指令独立。因为隔离范围未通过原型继承连接到其他范围。它确保指令外的更改仅通过绑定影响它。反之亦然。
如果您想使指令的内容更加灵活,可以使用transclude:true
。但是transclude: true
被设计为与隔离范围无关。 Angular为transcluded
内容创建了新范围。此范围是隔离范围的兄弟。因此,被转换的内容无法访问隔离范围上的值。
例如,假设我们有一个指令modal
。该指令仅关注弹出窗口,背景,结束,位置等。但在modal
内,我们可以通过transclude: true
放置任何内容。此内容不应与指令modal
建立连接。
还有另一种方法可以达到你想要的效果:Plunker。
将templateUrl
指定为函数,该函数根据某些输入参数返回模板名称:
templateUrl: function (elem, attrs) {
return 'template-' + attrs.tpl + '.html';
}
使用时:
<technique idnum='{{id}}' tpl="a"></technique>
<technique idnum='{{id}}' tpl="b"></technique>
通过这种方式,您可以使用不同的模板呈现相同的techniqueJSON
。