1

我有一个自定义指令,它只是将一个模板编译成另一个模板。

.directive('staticInclude', function($http, $templateCache, $compile) {
        return function(scope, element, attrs) {
            var templatePath = attrs.staticInclude;
            //
            $http.get(templatePath, {
                cache: $templateCache
            }).success(function(response) {
                var contents = element.html(response).contents();
                $compile(contents)(scope);
            });
        };
    });

我像这样使用它:

<div static-include="components/campaign/details.html"></div>

因为我为控制器使用别名(使用角度 UI 路由器),所以任何模板中的所有模型都像:

<p>Delivery Time: <span class="text-medium">{{CtrlAlias.campaign.newsletter.sentDate | date:CtrlAlias.currentUser.params.settings}}</span></p>

如何使此指令在 CtrlAlias 更改的多个模板中工作?

我尝试更改 $compile(contents)(scope); 进入 $compile(contents)(scope.newCtrlAlias);

有任何想法吗?

4

2 回答 2

3

When you $compile and then link, you are free to provide your own scope against which the compiled content is linked. That means that you can have the template content refer to some arbitrary ViewModel name, say vm:

<p>Delivery Time: <span>{{vm.campaign.newsletter.sentDate}}</span></p>

And link against a scope that has vm property:

var scope = { vm: {...} }

It actually might be even useful to use an isolate scope for your compiled content, to make sure that you aren't assuming an existence of scope variables that may or may not be there when the content is linked:

.directive('staticInclude', function($templateRequest, $compile) {
  return {
    link: function(scope, element, attrs){
       var alias = attrs.alias || 'vm';
       var templatePath = attrs.staticInclude;

       var newScope = scope.$new(true); // isolate scope
       newScope.vm = scope[alias];

       // $templateRequest is essentially $http with $templateCache
       $templateRequest(templatePath)
           .then(function(html){
              $compile(html)(newScope, function cloneAttachFn(clone){
                 element.empty();
                 element.append(clone);
              });
           });
    }
  };
});

Then usage is like so:

<div ng-controller="MainCtrl as main">
    <div static-include="components/campaign/details.html" alias="main">
    </div>
</div>
于 2015-07-25T22:36:52.970 回答
0

真的不确定我是否理解您为什么需要使用它,所以不容易回答。但是,一种可能的解决方案是将模板包装在<div>您可以附加所需控制器信息的模板中。这有点恶心,但它可能对你有用。您必须传入控制器名称和它的别名,但您也许可以将其添加到您$state的数据属性中并从中访问它们,但这一切似乎有点老套。

演示

app.directive('staticInclude', function($http, $templateCache, $compile) {

  return {

    scope: {
      ctrlName    : '@',
      alias       : '@'
    },

    link: link

  };


  function link(scope, element, attrs) {

      var templatePath = attrs.staticInclude;

      $http
        .get(templatePath, {
            cache: $templateCache
        })
        .success(function(response) {

          var ctrlStr   = scope.ctrlName + ' as ' + scope.alias,
              template  = '<div ng-controller="' + ctrlStr + '" >' + response + '</div>',
              contents  = element.html(template).contents();

            $compile(contents)(scope);

        });

  };

});
于 2015-07-25T11:49:09.597 回答