44

我想在 3 个地方使用相同的 HTML 模板,只是每次都使用不同的模型。我知道我可以从模板访问变量,但名称会有所不同。

有没有办法将模型传递给 ngInclude?

这是我想要实现的,当然属性 add-variable 现在不起作用。然后在我包含的模板中,我将访问 detailsObject 及其属性。

<pane title="{{projectSummary.ProjectResults.DisplayName}}">
    <h2>{{projectSummary.ProjectResults.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" init-variable="{'detailsObject': projectSummary.ProjectResults}"></ng-include>
</pane>

<pane  title="Documents" header="true"></pane>

<pane ng-repeat="document in projectSummary.DocumentResults" title="{{document.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': document}"></ng-include>
</pane>

<pane ng-repeat="header in [1]" title="Languages" header="true"></pane>

<pane ng-repeat="language in projectSummary.ResultsByLanguagePairs" title="{{language.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': language}"></ng-include>
</pane>

如果我在使用 ng-include 时采取了不好的方法,还有什么我应该尝试的吗?

4

6 回答 6

61

有一个相当简单的解决方案,尽管我必须承认,这不是 Misko 推荐的。但是,如果创建指令对您来说太过分了并且获得 Brice 的补丁是不可行的,那么以下内容将对您有所帮助。

<div ng-repeat="name in ['A']" ng-include="'partial.html'"></div>
<div ng-repeat="name in ['B']" ng-include="'partial.html'"></div>

<script type="text/ng-template" id="partial.html">
   <div>{{ name }}</div>
</script>

很明显它为什么起作用。在此处查看示例:http: //jsfiddle.net/Cndc6/4/

于 2013-12-17T16:13:18.853 回答
21

注意:这不是我最初的答案,但这是我在使用 angular 一段时间后会这样做的方式。

我将创建一个带有 html 模板的指令作为将动态数据传递给指令的标记,如本小提琴所示。

此示例的步骤/注释:

  1. 在用于将数据传递到指令中的和属性中定义一个带有标记templateUrl的指令(type在此示例中命名)。
  2. 使用模板中的指令数据(type在本例中命名)。
  3. 在标记中使用指令时,请确保将数据从控制器范围传递到指令(<address-form type="billing"></address-form>(其中计费正在访问控制器范围上的对象)。
  4. 请注意,在定义指令时,名称是驼峰式的,但在标记中使用时,它是小写破折号分隔的(即,它addressForm在 js 中命名,但address-form在 html 中命名)。可以在此处的 angular 文档中找到有关此的更多信息。

这是js:

var myApp = angular.module('myApp',[]);

angular.module('myApp').directive('addressForm', function() {
    return {
        restrict: 'E',
        templateUrl: 'partials/addressform.html', // markup for template
        scope: {
            type: '=' // allows data to be passed into directive from controller scope
        }
    };
});

angular.module('myApp').controller('MyCtrl', function($scope) {
    // sample objects in the controller scope that gets passed to the directive
    $scope.billing = { type: 'billing type', value: 'abc' };
    $scope.delivery = { type: 'delivery type', value: 'def' };
});

带标记:

<div ng-controller="MyCtrl">
    <address-form type="billing"></address-form>
    <address-form type="delivery"></address-form>
</div>

原始答案(这与使用指令 BTW 完全不同)。

注意:由于错误,下面我原始答案中的小提琴似乎不再起作用(但将其保留在这里以防它仍然有用)

Google Group 上对此进行了讨论,您可以在此处查看

看起来此功能不支持开箱即用,但您可以使用 Brice 的补丁,如本文所述。

这是他的jsfiddle的示例代码:

<script id="partials/addressform.html" type="text/ng-template">
    partial of type {{type}}<br>
</script>

<div ng-controller="MyCtrl">
  <ng-include src="'partials/addressform.html'" onInclude="type='billing'"></ng-include>
  <ng-include src="'partials/addressform.html'" onLoad="type='delivery'"></ng-include>
</div>
于 2012-11-16T19:31:54.493 回答
14

有一个解决这个问题的方法,但它看起来已经死了: https ://github.com/angular/angular.js/pull/1227

在不修改 Angular 源代码的情况下,这将以一种可重用且不太老套的方式解决问题:

directive('newScope', function() {
    return {
        scope: true,
        priority: 450,
    };
});

还有一个例子:

<div new-scope ng-init="myVar = 'one instance'" ng-include="'template.html'"></div>
<div new-scope ng-init="myVar = 'another instance'" ng-include="'template.html'"></div>

这是它的一个 Plunker: http ://plnkr.co/edit/El8bIm8ta97MNRglfl3n

于 2014-01-23T17:58:46.243 回答
6
<div new-scope="myVar = 'one instance'" ng-include="'template.html'"></div>

directive('newScope', function () {
    return {
        scope: true,
        priority: 450,
        compile: function () {
            return {
                pre: function (scope, element, attrs) {
                    scope.$eval(attrs.newScope);
                }
            };
        }
    };
});

这是一个指令,它结合new-scopeJohn Culviner 的答案和 Angular 的代码ng-init

为了完整起见,这是Angular 1.2 26 ng-init 源代码,您可以看到 new-scope 指令的唯一变化是添加了scope: true

{
  priority: 450,
  compile: function() {
    return {
      pre: function(scope, element, attrs) {
        scope.$eval(attrs.ngInit);
      }
    };
  }
}
于 2014-10-09T17:07:59.373 回答
5

Quick'n'dirty 解决方案:

<div ng-init="details=document||language||projectSummary.ProjectResults">
于 2012-11-16T19:40:16.463 回答
1

我听你的!ng-include 不是那么可重用,因为它可以访问全局范围。这有点奇怪。

应该有一种方法来设置局部变量。使用新指令而不是 ng-include是一种更简洁的解决方案。

理想的用法如下所示:

<div ng-include-template="'Partials/SummaryDetails.html'" ng-include-variables="{ 'detailsObject': language }"></div>

该指令是:

.directive(
  'ngIncludeTemplate'
  () ->
    {
      templateUrl: (elem, attrs) -> attrs.ngIncludeTemplate
      restrict: 'A'
      scope: {
        'ngIncludeVariables': '&'
      }
      link: (scope, elem, attrs) ->
        vars = scope.ngIncludeVariables()
        for key, value of vars
          scope[key] = value
    }
)

您可以看到该指令不使用全局范围。相反,它从 ng-include-variables 读取对象并将这些成员添加到它自己的本地范围内。

它干净而通用。

于 2015-10-25T18:10:07.903 回答