【问题标题】:Angularjs templateUrl fails to bind attributes inside ng-repeatAngularjs templateUrl 无法在 ng-repeat 中绑定属性
【发布时间】:2015-02-09 16:31:37
【问题描述】:

我正在使用指令来显示 html sn-ps。

和指令里面的templateUrl, 能够将 sn-ps 包含为 html 文件。

如果我尝试调用,该指令不起作用 在内置的 ng-repeat 指令中 ({{snip}} 按原样传递,没有替代):

div ng-repeat="snip in ['snippet1.html','snippet2.html']">
  <my-template snippet="{{snip}}"></my-template>
</div>

作为参考,这里是指令:

app.directive("myTemplate", function() {
return {
    restrict: 'EA',
    replace: true,
    scope: { snippet: '@'},
    templateUrl: function(elem, attrs) {
      console.log('We try to load the following snippet:' + attrs.snippet);
      return attrs.snippet;
    }
  };
});

还有一个plunker demo

非常感谢任何指针。 (指令在我的代码中更复杂, 我试图得到一个最小的例子,这个问题是可重现的。)

【问题讨论】:

标签: angularjs angularjs-directive angularjs-ng-repeat


【解决方案1】:

templateUrlattrs 参数在指令执行期间未插入。您可以使用以下方式来实现这一点

app.directive("myTemplate", function() {
  return {
    restrict: 'EA',
    replace: false,
    scope: { snippet: '@'},
    template: '<div ng-include="snippet"></div>'
  };
}); 

演示:http://plnkr.co/edit/2ofO6m45Apmq7kbYWJBG?p=preview

【讨论】:

  • 一种解决方法。最终的 DOM 看起来像这样:&lt;my-template&gt;&lt;div class="ng-scope" ng-include="snippet"&gt;&lt;div&gt; 我的 sn-p &lt;/div&gt;&lt;/div&gt;&lt;/my-template&gt; 的内容。谢谢你的想法。
  • @Doug、Rajeshwar 和您提供了基本相同的解决方案。我将您的回复标记为解决方案,因为您使用的是单向数据绑定 (@),而不是双向数据绑定 (=) 或 $observe,所以它稍微优雅一些​​。一个小的修改'@' 应该是'@snippet',该指令只需要它的父作用域中的这个变量。我不喜欢这样的事实,模板文件嵌入在 DOM 树中,又多了两层。但是 pankajparkar 解决方案可能有点矫枉过正。
  • 我最终修改了这两行:scope: { snippet: '@snippet'},template: '&lt;div ng-include="\'app/partials/\' + snippet"&gt;&lt;/div&gt;'。您能否更新您的答案,并出于存档原因还包括来自plunker 的所有内容? (html, js, 两个sn-ps)
【解决方案2】:

查看此链接

http://plnkr.co/edit/TBmTXztOnYPYxV4qPyjD?p=preview

app.directive("myTemplate", function() {
  return {
    restrict: 'EA',
    replace: true,
    scope: { snippet: '=snippet'},
    link: function(scope, elem, attrs) {
      console.log('We try to load the following snippet:' + scope.snippet);
    },
    template: '<div ng-include="snippet"></div>'
  };
})

【讨论】:

  • 您没有包含 html sn-ps 的 content,而是显示了 html sn-ps 的 filename。您能否调整您的解决方案以包含 sn-ps 的内容?
  • @arcol,请检查相同的 plunker 链接,您提到的更改已实施。
  • ng-include 将再次创建隔离范围
【解决方案3】:

您可以使用ng-include,观看 attrs。像这样:

app.directive("myTemplate", function() {
    return {
        restrict: 'E',
        replace: true,
        link: function(scope, elem, attrs) {
            scope.content = attrs.snippet;
            attrs.$observe("snippet",function(v){
                scope.content = v;
            });
        },
        template: "<div data-ng-include='content'></div>"
    };
});

【讨论】:

  • 在您的指令中,scope.content 将具有值“snip”,而不是我们从标记传递的值。
【解决方案4】:

刚刚对指令结构进行了更改。我们将使用指令本身来呈现它,而不是使用ng-repeat 呈现所有模板,因为我们会将整个模板数组传递给指令。

HTML

<div ng-init="snippets = ['snippet1.html','snippet2.html']">
    <my-template snippets="snippets"></my-template>
</div>

指令

angular.module('myApp', [])
.controller('test',function(){})
    .directive("myTemplate", function ($templateCache, $compile) {
    return {
        restrict: 'EA',
        replace: true,
        scope: {
            snippets: '='
        },
        link: function(scope, element, attrs){
            angular.forEach(scope.snippets, function(val, index){
                //creating new element inside angularjs
                element.append($compile($templateCache.get(val))(scope));
            });
        }
    };
});

Working Fiddle

希望这可以帮助你。谢谢。

【讨论】:

  • 原始请求中未指定,但我希望将 html sn-ps 放在单独的文件中。它看起来是普通的 html,可以由第三方(即网页设计师)编辑。阅读$templateCache 文档,您可以使用带有字符串的$templateCache.put,或者通过&lt;script type="text/ng-template" id="templateId.html"&gt; 标记将模板放在主html 中。我错过了什么明显的东西吗?
  • @arcol 你是对的,你也可以放入html ..只有你需要在角度的运行阶段将那些html模板放入$templateCache。参考这个stackoverflow.com/questions/27785564/…
  • 您只需要这样做app.run(['$templateCache','$q','$http', function($templateCache, $http){ $http.get('partials/views/template1.html',{ cache : $templateCache }); $http.get('partials/views/template2.html',{ cache : $templateCache }); }]); 将html 放入$templateCache
  • 我试图让它与你的解决方案一起工作,但我卡住了:plnkr.co/edit/IYZHcmSkX7zkM9o0NEFe
【解决方案5】:

您似乎正在尝试基于某些逻辑来获得不同的观点 并且您使用了 templateUrl 函数,但 Angular 插值不起作用,来解决这个问题

不要使用templateUrl

那么如何在不使用 templateUrl 的情况下做到这一点

就这样

app.directive("myTemplate", function() {
    return {
        link: function(scope, elem, attrs) {
           $scope.templateUrl = '/ActivityStream/activity-' + $scope.ativity.type + '.html'
        },
        template: "<div data-ng-include='templateUrl'></div>"
    };
});

希望这简单易懂

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多