Html 如何在 AngularJS 中为 ngInclude 指令指定模型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13422966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 03:55:28  来源:igfitidea点击:

How to specify model to a ngInclude directive in AngularJS?

htmltemplatesangularjs

提问by Tomas Grosup

I would like to use the same HTML template in 3 places, just each time with a different model. I know I can access the variables from the template, but there names will be different.

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

Is there a way to pass a model to the ngInclude?

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

This is what I would like to achieve, of course the attribute add-variable does not work now. Then in my included template, I would acces the detailsObject and its properties.

这就是我想要实现的,当然属性 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>

If I took a bad approach with using ng-include, is there something else I should try?

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

采纳答案by Gloopy

NOTE: this is not my original answer but this is how I'd do this after using angular for a bit.

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

I would create a directive with the html template as the markup passing in the dynamic data to the directive as seen in this fiddle.

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

Steps/notes for this example:

此示例的步骤/注释:

  1. Define a directive with markup in the templateUrland attribute(s) used to pass data into the directive (named typein this example).
  2. Use the directive data in the template (named typein this example).
  3. When using the directive in the markup make sure you pass in the data from the controller scope to the directive (<address-form type="billing"></address-form>(where billing is accessing an object on the controller scope).
  4. Note that when defining a directive the name is camel cased but when used in the markup it is lower case dash delimited (ie it's named addressFormin the js but address-formin the html). More info on this can be found in the angular docs here.
  1. templateUrl用于将数据传递到指令(type在此示例中命名)的属性中定义带有标记的指令。
  2. 使用模板中的指令数据(type在本例中命名)。
  3. 在标记中使用指令时,请确保将数据从控制器范围传递到指令(<address-form type="billing"></address-form>(其中 billing 正在访问控制器范围内的对象)。
  4. 请注意,当定义指令时,名称是驼峰式的,但在标记中使用时,它是小写的破折号分隔的(即它addressForm在 js 中命名,但address-form在 html 中)。可以在此处的 angular 文档中找到关于此的更多信息。

Here is the js:

这是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' };
});

With markup:

带标记:

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


ORIGINAL ANSWER (which is completely different than using a directive BTW).

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

Note: The fiddle from my original answer below doesn't appear to work anymore due to an error (but keeping it here in case it is still useful)

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

There was a discussion about this on the Google Group you can see it here.

您可以在此处查看Google Group 上对此的讨论。

It looks like this functionality is not supported out of the box but you can use Brice's patch as described in this post.

它看起来像这样的功能不支持开箱即用,但你可以使用布莱斯的补丁中描述的这个帖子

Here is the sample code from his jsfiddle:

这是他的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>

回答by Denis Pshenov

There is a rather simple solution, although I must admit, it's not what Misko would recommend. But if creating a directive is an overkill for you and getting Brice's patch is not feasible then the following will help you.

有一个相当简单的解决方案,尽管我必须承认,这不是 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>

It's quite evident why it works. See an example here: http://jsfiddle.net/Cndc6/4/

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

回答by John Culviner

There is a pull to fix this but it looks like it's dead: https://github.com/angular/angular.js/pull/1227

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

Without modifying the Angular source code this will solve the problem in a reusable not-too-hacky-feeling way:

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

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

And an example:

和一个例子:

<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>

Here is a Plunker of it in action: http://plnkr.co/edit/El8bIm8ta97MNRglfl3n

这是它在行动中的一个 Plunker:http://plnkr.co/edit/El8bIm8ta97MNRglfl3n

回答by Ande

<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);
                }
            };
        }
    };
});

This is a directive that combines new-scopefrom John Culviner's answerwith code from Angular's ng-init.

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

For completeness, this is the Angular 1.2 26 ng-init source, you can see the only change in the new-scope directive is the addition of scope: true

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

{
  priority: 450,
  compile: function() {
    return {
      pre: function(scope, element, attrs) {
        scope.$eval(attrs.ngInit);
      }
    };
  }
}

回答by Tomas Grosup

Quick'n'dirty solution:

快速解决方案:

<div ng-init="details=document||language||projectSummary.ProjectResults">

回答by Tanin

I hear you! ng-include is not that reusable because it has access to the global scope. It's a little weird.

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

There should be a way to set local variables. Using a new directive instead of ng-includeis a cleaner solution.

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

The ideal usage looks like:

理想的用法如下:

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

The directive is:

该指令是:

.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
    }
)

You can see that the directive doesn't use the global scope. Instead, it reads the object from ng-include-variables and add those members to its own local scope.

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

It's clean and generic.

它干净而通用。