供设计师使用的AngularJS自包含指令
我正在使用一个web应用程序,它允许设计人员通过编写html并结合我和其他开发人员创建的angularjs指令来创建页面。我正在努力寻找用数据填充指令的最佳方法 最初的尝试是使所有指令完全独立。因此,例如,产品页面可能如下所示(为清晰起见,所有这些页面都有自定义html):供设计师使用的AngularJS自包含指令,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我正在使用一个web应用程序,它允许设计人员通过编写html并结合我和其他开发人员创建的angularjs指令来创建页面。我正在努力寻找用数据填充指令的最佳方法 最初的尝试是使所有指令完全独立。因此,例如,产品页面可能如下所示(为清晰起见,所有这些页面都有自定义html): 如果指令需要数据(几乎所有指令都需要),它们将使用服务调用web API并获取所需的数据。这种方法产生了一些问题 指令通常需要来自父级或同级的一些信息。在下面的示例中,product image可能需要ProductID
如果指令需要数据(几乎所有指令都需要),它们将使用服务调用web API并获取所需的数据。这种方法产生了一些问题
<product-image product-url="vm.product.imageUrl" ng-if="vm.product"></product-image>
这解决了#2太多API和数据库调用的问题,但向设计器公开了太多的内部构件。现在,设计师必须知道如何传递产品url,并且必须了解幕后有一个vm.product。他甚至可能需要理解一些angularJS(ng if)。我已经看到这个模式在Angular2中使用了很多,甚至有输入。对于开发人员使用来说似乎很好,但对于设计器使用的指令来说则不然。我们希望隐藏内部工作和复杂性,同时赋予设计器控制布局的能力
最后,我正在考虑使用父控制器来填充页面上可能需要的所有内容。然后所有的子指令都会像现在一样使用服务,但是数据已经加载,而不是调用API。这些指令仍然很简单,大部分是自包含的,但它们的数据加载是由父级触发的。我遇到的唯一问题是,由于设计器没有使用指令,我们可能会加载大量未使用的数据。但我觉得这是一个必要的权衡
是否有人构建了类似的东西,我缺少了哪些可能的方法?您可以在服务中使用组件树。 从设计师友好型开始:
<div ng-app="MyApp">
<product id="1">
<product-image></product-image>
</product>
</div>
类似这样的分类是有效的:
angular.module('MyApp', [])
.factory('api', function($q){
return {
loadProduct: function(id){
return $q.when({
id: id,
imageUrl: 'http://i2.cdn.turner.com/cnnnext/dam/assets/160407085910-setsuna-main-overlay-tease.jpg'
})
}
};
})
.component('product', {
transclude: true,
bindings: {
id: '='
},
template: [
'<div ng-transclude></div>'
].join(''),
controller: function(api) {
var self = this;
this.$onInit = function() {
self.data = api.loadProduct(this.id);
};
}
})
.component('productImage', {
require: {
product: '^product'
},
bindings: {
},
template: [
'<pre>{{ $ctrl.url | json }}</pre>'
].join(''),
controller: function() {
var self = this;
this.url = false;
this.$onInit = function() {
this.product.data.then(function(data){
self.url = data.imageUrl;
})
};
}
})
angular.module('MyApp',[])
.factory('api',函数($q){
返回{
loadProduct:函数(id){
返回$q.when({
id:id,
imageUrl:'http://i2.cdn.turner.com/cnnnext/dam/assets/160407085910-setsuna-main-overlay-tease.jpg'
})
}
};
})
.组件(“产品”{
是的,
绑定:{
id:“=”
},
模板:[
''
].加入(“”),
控制器:函数(api){
var self=这个;
这是。$onInit=function(){
self.data=api.loadProduct(this.id);
};
}
})
.component('productImage'{
要求:{
产品:“^product”
},
绑定:{
},
模板:[
“{{$ctrl.url | json}}”
].加入(“”),
控制器:函数(){
var self=这个;
this.url=false;
这是。$onInit=function(){
this.product.data.then(函数(数据){
self.url=data.imageUrl;
})
};
}
})
请参阅此代码笔:
我认为作为模型并处理所有API的服务没有问题。这种方法有什么问题?这个问题在当前状态下太模糊了。我在产品页面示例中添加了更多标记。那么,你会让产品控制器加载服务/模型中的所有数据,让孩子们使用这些数据吗?我会让服务完全基于承诺,更加灵活和一致$http承诺在第一次请求时缓存在服务中,在下一次请求时返回,并在需要时重新验证。使用状态/路由解析程序包装服务可能是有益的,因为解析程序注入承诺值,无需手动打开承诺。我喜欢此解决方案,但我看到的问题是,您失去了与父产品数据的双向绑定。例如,假设您在中更新数据,然后在中提交产品数据,您在中所做的任何更改仅存在于该指令中。不一定。。。有很多方法可以保持这些作用域的链接。。。(接受的答案?你想让我进一步调查吗?)
angular.module('MyApp', [])
.factory('api', function($q){
return {
loadProduct: function(id){
return $q.when({
id: id,
imageUrl: 'http://i2.cdn.turner.com/cnnnext/dam/assets/160407085910-setsuna-main-overlay-tease.jpg'
})
}
};
})
.component('product', {
transclude: true,
bindings: {
id: '='
},
template: [
'<div ng-transclude></div>'
].join(''),
controller: function(api) {
var self = this;
this.$onInit = function() {
self.data = api.loadProduct(this.id);
};
}
})
.component('productImage', {
require: {
product: '^product'
},
bindings: {
},
template: [
'<pre>{{ $ctrl.url | json }}</pre>'
].join(''),
controller: function() {
var self = this;
this.url = false;
this.$onInit = function() {
this.product.data.then(function(data){
self.url = data.imageUrl;
})
};
}
})