AngularJS自包含指令供设计师使用

时间:2016-04-14 13:58:57

标签: angularjs angularjs-directive

我正在使用一个Web应用程序,它允许设计人员通过将html与我自己和其他开发人员创建的angularjs指令结合使用来创建页面。我正在努力用数据填充指令的最佳方法。

最初的尝试是保持所有指令完全自包含。因此,例如,产品页面可能如下所示(围绕所有这些的自定义html - 为了清晰起见而遗漏):

<product>
    <product-information></product-information>
    <product-image></product-image>
    <product-quantities></product-quantities>
    <product-add-to-cart-button></product-add-to-cart-button>
</product>

如果指令需要数据(几乎所有人都这样做),他们将使用服务来调用Web API并获取他们需要的数据。这种方法出现了一些问题。

  1. 指令通常需要来自父母或兄弟姐妹的一些信息。在下面的示例中,product-image可能需要ProductID,以便它可以获得正确的图像。在这种情况下,我必须依赖从querystring参数获取信息或存储在最初由父指令填充的angularJS服务中。
  2. 很多API调用。由于每个指令都有自己的API调用,我现在最终得到的页面有15个以上的API调用要加载,并且可能会随着时间的推移而增长。即使很多数据可能密切相关(即使在同一个数据库表中)。显然这不太理想。
  3. 所以我开始用第二次传递来改变我的方法。现在,指令被设置为树结构,每个指令期望它的数据要求通过属性传递。这是一个例子:

    <product-image product-url="vm.product.imageUrl" ng-if="vm.product"></product-image>
    

    这解决了太多API和数据库调用的问题#2,但是向设计者公开了太多内部。现在设计师必须知道传递产品网址,并且必须了解幕后有一个vm.product。他甚至可能需要了解一些angularJS(ng-if)。我已经看到这种模式甚至在带有输入的Angular2中也使用了很多。看起来很适合开发人员使用但不适用于设计师使用的指令,我们希望隐藏内部工作和复杂性,同时赋予设计师控制布局的能力。

    最后,我正在考虑使用父控制器来填充页面上可能需要的所有内容。然后所有子指令将只使用他们现在的服务,但不是调用API,而是已经加载了数据。指令仍然很简单,大多是自包含的,但它们的数据加载是由父级触发的。我唯一的问题是,由于设计师没有使用指令,我们最终可能会加载大量未使用的数据。但我觉得这是一个必要的权衡。

    有没有人建造类似的东西,我有什么可能的方法吗?

1 个答案:

答案 0 :(得分:0)

您可以在服务中使用组件树。 从设计师友好开始:

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;
      })
    };
  }
})

像这样的东西有效:

DECLARE @query NVARCHAR(MAX) = 'SELECT ' + @myfield + ' FROM mytable WHERE ' + @myfield + ' IS NOT NULL ORDER BY ' + @myfield

EXEC sp_executesql @query

查看此CodePen: http://codepen.io/anon/pen/wGmEKP?editors=1011