0

我正在尝试在指令中自定义模板,并在父范围中包含对属性的引用。我对 Angular 还是很陌生,但我已经进行了相当多的搜索,并且我的尝试基于Customizing the template within a Directive。但是,如果我将对父作用域变量的引用作为属性传递给指令,则它不会得到解析,可能是因为在调用 compile 函数时它仍然未定义。

我的指令定义如下所示:

app.directive('sectionHeader', function() {
  return {
    restrict: 'EC',
    replace: true,
    transclude: true,
    scope: {sectionName:'@sectionName', imageUrl:'@imageUrl'},
    compile: function(element, attrs) {
      var imageHtml = attrs.hasOwnProperty('imageUrl') ? '<div style="float: left; padding-right: 5px;"><img class="float_left" src="' + attrs.imageUrl + '" alt=""/></div>' : '';
      var htmlText =
        '<div>' + imageHtml + '<h1 class="float-left">' + attrs.sectionName + '</h1>' +
        '<div class="clear"></div>' +
        '<div class="modal_hr"></div></div>';
      element.replaceWith(htmlText);
    },
  };
});

我正在使用这样的指令:

 <div class="section-header" section-name="{{currentFeatureName}}"></div>

问题是在指令上调用编译函数时,我的控制器中的 {{currentFeatureName}} 变量似乎没有定义。

我考虑过解决这个问题的一种方法是在 compile 函数中在 sectionName 属性上设置一个观察者函数,当它看到更改时更新 h1 元素内容。这似乎有点笨拙,我想知道是否有更好或更优雅的方式来做到这一点。

4

2 回答 2

1

你对为什么这不起作用是正确的。当编译和链接函数运行时,内插属性不可用,因为尚未发生摘要以将内插解析为值。您可以在此处阅读有关此内容的更多信息。您对解决方案也是正确的:使用attrs.$observe( 'sectionName', function ( val ) { ... });

但是,您似乎不需要动态模板。如果这是您的模板:

<div>
  <div style="float: left; padding-right: 5px;" ng-show="{{imageUrl}}">
    <img class="float_left" ng-src="{{imageUrl}}" alt="" />
  </div>
  <h1 class="float-left">{{sectionName}}</h1>
  <div class="clear"></div>
  <div class="modal_hr"></div>
</div>

那么你就不需要编译链接函数中的任何逻辑了。也许这种模式也会对您有所帮助。

于 2013-03-07T20:55:19.060 回答
1

查看Directive docs$observe中的函数。

但除此之外,实际上似乎没有必要做你想做的事情。看:

var app = angular.module('plunker', []);
app.controller('AppController',
    [
      '$scope',
      function($scope) {
        $scope.currentFeatureName = 'Current Feature Name';
        $scope.imageUrl = "https://lh3.googleusercontent.com/GYSBZh5RpCFwTU6db0JlHfOr_f-RWvSQwP505d0ZjWfqoovT3SYxIUPOCbUZNhLeN9EDRK3b2g=s128-h128-e365";
      }
    ]
  );

app.directive('sectionHeader', function() {
  return {
    restrict: 'EC',
    replace: true,
    transclude: true,
    scope: {
      sectionName:'@',
      imageUrl:'@'
    },
    template: '<div><div style="float: left; padding-right: 5px;" ng-show="imageUrl"><img class="float_left" ng-src="{{imageUrl}}" alt=""/></div><h1 class="float-left">{{sectionName}}</h1><div class="clear"></div><div class="modal_hr"></div></div>'
  };
});

HTML:

<div ng-controller="AppController">
  <div class="section-header" section-name="{{currentFeatureName}}" image-url="{{imageUrl}}"></div>
</div>

笨蛋。

于 2013-03-07T21:00:20.273 回答