2

我正在开发一个以特殊 XML 作为输入来呈现 HTML 的项目。我已经成功完成了基本案例。例如:

<mybutton name="layla"></mybutton>

被转换为

<div class="btn">Layla</div>

使用类似的指令

.directive('mybutton', function() {
    return {
        restrict: 'E',
        scope: {
            name: '@'
        },
        templateUrl: 'uicomponents/uiButton.html'
    }
})

我将收到的真正 XML 输入是:

<ui type="back_button" x="10.0" y="630.0"/>

我想避免更改 XML 语法,但如有必要,可以这样做。所有屏幕组件都在<ui></ui>标签中。该type属性定义了组件。

你会如何为这种标签编写指令?<ui>为元素创建一个巨大的指令并在内部为属性设置一个长开关盒似乎并不聪明。

4

2 回答 2

5

您可以创建一个 ui 指令,根据 type 属性转换元素,然后重新编译元素 - 如下所示:

app.directive('ui',function($compile){
  return {
    restrict:'E',
    compile:function(tElement,tAttrs){
      if(tAttrs.type){
        tElement.attr(tAttrs.type,'');
        tElement.removeAttr('type');
        return function(scope,el){
          $compile(el)(scope);
        }
      }

    }  
  }
});


app.directive('backButton',function(){
  return {
    replace:true,
    template:'<button ng-click="btnClick()">A back-button template</button>'
  }
});

编辑:在我最初的示例中,我犯了编译模板元素的错误——如果在 ngRepeat 中使用该指令,这将不起作用。修复很简单,而是编译链接元素。我已经更新了代码和示例。

查看这个 plnkr 示例

于 2013-04-10T18:04:49.180 回答
2

我不知道创建绑定属性值的指令的方法,但也许你可以看看这个以前的 SO 答案:自定义输入类型

这个想法是使用指令的编译功能根据属性的值创建不同的模板。您可以在开始时缓存所有自定义输入模板(不是必需的)。

angular.module('myapp', ['myapp.directives'])
    .run(['$http', '$templateCache', function($http, $templateCache) {
        $templateCache.put('span.html', '<span>text</span>');
        $http.get('back_button.html', {cache:$templateCache});
    }]);

并根据 type 属性从缓存中检索输入模板:

angular.module('myapp.directives', [])
    .directive('ui', ['$templateCache', function($templateCache) {
        return {
            restrict: 'E',
            compile: function(elem, attrs)
            {
                var type = attrs.type || 'span.html'; // default value ?
                elem.replaceWith($templateCache.get(type));
            }
        }
    }]);

此代码未经测试。

编辑:我认为,这也可以工作,使用带有 $compile 的链接函数,而不预加载模板,但仍然缓存它们:

angular.module('myapp.directives', [])
    .directive('ui', ['$http', '$templateCache', '$compile', function($http, $templateCache, $compile) {
        return {
            restrict: 'E',
            link: function(scope, elem, attrs)
            {
                var type = attrs.type || 'span.html'; // default value ?
                $http.get('views/' + type + '.html', {cache: $templateCache}).then(function(result) {
                    elem.replaceWith($compile(result.data)(scope));
                });
            }
        }
    }]);

这段代码对我有用。

于 2013-04-10T17:47:19.607 回答